auth log save to db and simple show

This commit is contained in:
DASHU
2024-09-06 12:15:17 +08:00
parent dd1722324d
commit ac73133d81
9 changed files with 232 additions and 34 deletions

View File

@@ -0,0 +1,38 @@
import 'dart:async';
import 'package:flutter/material.dart';
abstract class CustState<T extends StatefulWidget> extends State<T> {
bool isInited = false;
bool readyComplete = false;
@override
Widget build(BuildContext context) {
Widget w = doBuild(context);
if (!isInited) {
isInited = true;
WidgetsBinding.instance.addPostFrameCallback((_) {
this.onReady(context);
readyComplete = true;
});
}
return w;
}
Widget doBuild(BuildContext context);
Future<void> onReady(BuildContext context);
// @override
// void dispose() {
// super.dispose();
// }
// @override
// void initState() {
// super.initState();
// }
}

View File

@@ -214,7 +214,7 @@ class _WebViewComponent extends State<WebViewComponent>
} }
checkPermission(context, AppType.WEB, code, AuthType.GET_PUBLIC_KEY, checkPermission(context, AppType.WEB, code, AuthType.GET_PUBLIC_KEY,
() { (app) {
nip07Reject(resultId, "Forbid"); nip07Reject(resultId, "Forbid");
}, (app, signer) { }, (app, signer) {
print("confirm get pubkey"); print("confirm get pubkey");
@@ -243,7 +243,7 @@ class _WebViewComponent extends State<WebViewComponent>
var eventKind = eventObj["kind"]; var eventKind = eventObj["kind"];
if (eventKind is int) { if (eventKind is int) {
checkPermission(context, AppType.WEB, code, AuthType.SIGN_EVENT, checkPermission(context, AppType.WEB, code, AuthType.SIGN_EVENT,
eventKind: eventKind, authDetail: content, () { eventKind: eventKind, authDetail: content, (app) {
nip07Reject(resultId, "Forbid"); nip07Reject(resultId, "Forbid");
}, (app, signer) async { }, (app, signer) async {
var tags = eventObj["tags"]; var tags = eventObj["tags"];
@@ -281,7 +281,7 @@ class _WebViewComponent extends State<WebViewComponent>
return; return;
} }
checkPermission(context, AppType.WEB, code, AuthType.GET_RELAYS, () { checkPermission(context, AppType.WEB, code, AuthType.GET_RELAYS, (app) {
nip07Reject(resultId, "Forbid"); nip07Reject(resultId, "Forbid");
}, (app, signer) { }, (app, signer) {
// TODO handle getRelays // TODO handle getRelays
@@ -319,7 +319,7 @@ class _WebViewComponent extends State<WebViewComponent>
} }
checkPermission(context, AppType.WEB, code, AuthType.NIP04_ENCRYPT, checkPermission(context, AppType.WEB, code, AuthType.NIP04_ENCRYPT,
() { (app) {
nip07Reject(resultId, "Forbid"); nip07Reject(resultId, "Forbid");
}, (app, signer) async { }, (app, signer) async {
var resultStr = await signer.encrypt(pubkey, plaintext); var resultStr = await signer.encrypt(pubkey, plaintext);
@@ -351,7 +351,7 @@ class _WebViewComponent extends State<WebViewComponent>
} }
checkPermission(context, AppType.WEB, code, AuthType.NIP04_DECRYPT, checkPermission(context, AppType.WEB, code, AuthType.NIP04_DECRYPT,
() { (app) {
nip07Reject(resultId, "Forbid"); nip07Reject(resultId, "Forbid");
}, (app, signer) async { }, (app, signer) async {
var app = appProvider.getApp(AppType.WEB, code); var app = appProvider.getApp(AppType.WEB, code);
@@ -386,7 +386,7 @@ class _WebViewComponent extends State<WebViewComponent>
} }
checkPermission(context, AppType.WEB, code, AuthType.NIP44_ENCRYPT, checkPermission(context, AppType.WEB, code, AuthType.NIP44_ENCRYPT,
() { (app) {
nip07Reject(resultId, "Forbid"); nip07Reject(resultId, "Forbid");
}, (app, signer) async { }, (app, signer) async {
var resultStr = await signer.nip44Encrypt(pubkey, plaintext); var resultStr = await signer.nip44Encrypt(pubkey, plaintext);
@@ -418,7 +418,7 @@ class _WebViewComponent extends State<WebViewComponent>
} }
checkPermission(context, AppType.WEB, code, AuthType.NIP44_DECRYPT, checkPermission(context, AppType.WEB, code, AuthType.NIP44_DECRYPT,
() { (app) {
nip07Reject(resultId, "Forbid"); nip07Reject(resultId, "Forbid");
}, (app, signer) async { }, (app, signer) async {
var resultStr = await signer.nip44Decrypt(pubkey, ciphertext); var resultStr = await signer.nip44Decrypt(pubkey, ciphertext);

View File

@@ -1,3 +1,5 @@
import 'package:flutter/material.dart';
class AuthType { class AuthType {
static const GET_PUBLIC_KEY = 1; static const GET_PUBLIC_KEY = 1;
@@ -12,4 +14,24 @@ class AuthType {
static const NIP44_ENCRYPT = 6; static const NIP44_ENCRYPT = 6;
static const NIP44_DECRYPT = 7; static const NIP44_DECRYPT = 7;
static String getAuthName(BuildContext context, int authType) {
if (authType == GET_PUBLIC_KEY) {
return "Get Public Key";
} else if (authType == SIGN_EVENT) {
return "Sign Event";
} else if (authType == GET_RELAYS) {
return "Get Relays";
} else if (authType == NIP04_ENCRYPT) {
return "Encrypt (NIP-04)";
} else if (authType == NIP04_DECRYPT) {
return "Decrypt (NIP-04)";
} else if (authType == NIP44_ENCRYPT) {
return "Encrypt (NIP-44)";
} else if (authType == NIP44_DECRYPT) {
return "Decrypt (NIP-44)";
}
return "Unknow";
}
} }

View File

@@ -1 +1,35 @@
class AuthLogDB {} import 'package:nowser/data/auth_log.dart';
import 'package:sqflite/sqflite.dart';
import 'db.dart';
class AuthLogDB {
static Future<List<AuthLog>> list(
{DatabaseExecutor? db, int? appId, int? skip, int? limit}) async {
List<AuthLog> objs = [];
List<Object?>? arguments = [];
db = await DB.getDB(db);
var sql = "select * from auth_log where 1 = 1";
if (appId != null) {
sql += " and app_id = ?";
arguments.add(appId);
}
sql += " order by created_at desc";
if (skip != null && limit != null) {
sql += " limit ?, ?";
arguments.add(skip);
arguments.add(limit);
}
List<Map<String, dynamic>> list = await db.rawQuery(sql, arguments);
for (var i = 0; i < list.length; i++) {
var json = list[i];
objs.add(AuthLog.fromJson(json));
}
return objs;
}
static Future<int> insert(AuthLog o, {DatabaseExecutor? db}) async {
db = await DB.getDB(db);
return await db.insert("auth_log", o.toJson());
}
}

View File

@@ -92,9 +92,12 @@ mixin AndroidSignerMixin on PermissionCheckMixin {
} }
checkPermission(context, AppType.ANDROID_APP, code!, authType, checkPermission(context, AppType.ANDROID_APP, code!, authType,
eventKind: eventKind, authDetail: playload, () { eventKind: eventKind, authDetail: playload, (app) {
// this place should do some about reject // this place should do some about reject
// saveAuthLog(app, authType, eventKind, playload, AuthResult.OK); if (app != null) {
saveAuthLog(
app, authType, eventKind, playload, AuthResult.REJECT);
}
receiveIntent.ReceiveIntent.setResult( receiveIntent.ReceiveIntent.setResult(
receiveIntent.kActivityResultCanceled, receiveIntent.kActivityResultCanceled,
shouldFinish: true, shouldFinish: true,

View File

@@ -11,12 +11,18 @@ class AppProvider extends ChangeNotifier {
List<App> get appList => _list; List<App> get appList => _list;
Map<int, App> _appMap = {};
Map<String, Map<String, int>> appPermissions = {}; Map<String, Map<String, int>> appPermissions = {};
Future<void> reload() async { Future<void> reload() async {
_appMap = {};
appPermissions = {}; appPermissions = {};
var allApp = await AppDB.all(); var allApp = await AppDB.all();
_list = allApp; _list = allApp;
for (var app in allApp) {
_appMap[app.id!] = app;
}
notifyListeners(); notifyListeners();
} }
@@ -91,6 +97,10 @@ class AppProvider extends ChangeNotifier {
} }
} }
App? getAppById(int appId) {
return _appMap[appId];
}
App? getApp(int appType, String code) { App? getApp(int appType, String code) {
for (var app in _list) { for (var app in _list) {
if (app.appType == appType && app.code == code) { if (app.appType == appType && app.code == code) {

View File

@@ -4,6 +4,7 @@ import 'package:nowser/component/auth_dialog/auth_app_connect_dialog.dart';
import 'package:nowser/component/auth_dialog/auth_dialog.dart'; import 'package:nowser/component/auth_dialog/auth_dialog.dart';
import 'package:nowser/const/auth_result.dart'; import 'package:nowser/const/auth_result.dart';
import 'package:nowser/data/auth_log.dart'; import 'package:nowser/data/auth_log.dart';
import 'package:nowser/data/auth_log_db.dart';
import 'package:nowser/main.dart'; import 'package:nowser/main.dart';
import '../const/connect_type.dart'; import '../const/connect_type.dart';
@@ -11,7 +12,7 @@ import '../data/app.dart';
mixin PermissionCheckMixin { mixin PermissionCheckMixin {
Future<void> checkPermission(BuildContext context, int appType, String code, Future<void> checkPermission(BuildContext context, int appType, String code,
int authType, Function reject, Function(App, NostrSigner) confirm, int authType, Function(App?) reject, Function(App, NostrSigner) confirm,
{int? eventKind, String? authDetail}) async { {int? eventKind, String? authDetail}) async {
var app = appProvider.getApp(appType, code); var app = appProvider.getApp(appType, code);
if (app == null) { if (app == null) {
@@ -24,13 +25,14 @@ mixin PermissionCheckMixin {
if (app == null) { if (app == null) {
// not allow connect // not allow connect
reject(); reject(null);
return; return;
} }
var signer = getSigner(app.pubkey!); var signer = getSigner(app.pubkey!);
if (signer == null) { if (signer == null) {
reject(); saveAuthLog(app, authType, eventKind, authDetail, AuthResult.REJECT);
reject(app);
return; return;
} }
@@ -48,7 +50,7 @@ mixin PermissionCheckMixin {
return; return;
} else if (permissionCheckResult == AuthResult.REJECT) { } else if (permissionCheckResult == AuthResult.REJECT) {
saveAuthLog(app, authType, eventKind, authDetail, AuthResult.REJECT); saveAuthLog(app, authType, eventKind, authDetail, AuthResult.REJECT);
reject(); reject(app);
return; return;
} }
@@ -62,13 +64,24 @@ mixin PermissionCheckMixin {
} }
saveAuthLog(app, authType, eventKind, authDetail, AuthResult.REJECT); saveAuthLog(app, authType, eventKind, authDetail, AuthResult.REJECT);
reject(); reject(app);
return; return;
} }
void saveAuthLog(App app, int authType, int? eventKind, String? authDetail, void saveAuthLog(App app, int authType, int? eventKind, String? authDetail,
int authResult) { int authResult) {
// TODO if (app.id != null) {
var authLog = AuthLog(
appId: app.id,
authType: authType,
eventKind: eventKind,
content: authDetail,
authResult: authResult,
createdAt: DateTime.now().millisecondsSinceEpoch ~/ 1000,
);
AuthLogDB.insert(authLog);
}
} }
// this method should override // this method should override

View File

@@ -1,9 +1,11 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:nowser/component/cust_state.dart';
import 'package:nowser/component/text_input/text_input_dialog.dart'; import 'package:nowser/component/text_input/text_input_dialog.dart';
import 'package:nowser/component/user/user_name_component.dart'; import 'package:nowser/component/user/user_name_component.dart';
import 'package:nowser/component/user/user_pic_component.dart'; import 'package:nowser/component/user/user_pic_component.dart';
import 'package:nowser/const/base.dart'; import 'package:nowser/const/base.dart';
import 'package:nowser/const/router_path.dart'; import 'package:nowser/const/router_path.dart';
import 'package:nowser/data/auth_log_db.dart';
import 'package:nowser/provider/app_provider.dart'; import 'package:nowser/provider/app_provider.dart';
import 'package:nowser/provider/key_provider.dart'; import 'package:nowser/provider/key_provider.dart';
import 'package:nowser/router/me/me_router_log_item_component.dart'; import 'package:nowser/router/me/me_router_log_item_component.dart';
@@ -11,6 +13,7 @@ import 'package:nowser/router/me/me_router_web_item_component.dart';
import 'package:nowser/util/router_util.dart'; import 'package:nowser/util/router_util.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import '../../data/auth_log.dart';
import '../keys/keys_router.dart'; import '../keys/keys_router.dart';
import 'me_router_app_item_component.dart'; import 'me_router_app_item_component.dart';
@@ -21,9 +24,19 @@ class MeRouter extends StatefulWidget {
} }
} }
class _MeRouter extends State<MeRouter> { class _MeRouter extends CustState<MeRouter> {
List<AuthLog> authLogs = [];
@override @override
Widget build(BuildContext context) { Future<void> onReady(BuildContext context) async {
var list = await AuthLogDB.list(skip: 0, limit: 10);
setState(() {
authLogs = list;
});
}
@override
Widget doBuild(BuildContext context) {
var mediaQueryData = MediaQuery.of(context); var mediaQueryData = MediaQuery.of(context);
var themeData = Theme.of(context); var themeData = Theme.of(context);
var _appProvider = Provider.of<AppProvider>(context); var _appProvider = Provider.of<AppProvider>(context);
@@ -150,7 +163,7 @@ class _MeRouter extends State<MeRouter> {
List<Widget> appWidgetList = []; List<Widget> appWidgetList = [];
var appList = _appProvider.appList; var appList = _appProvider.appList;
var length = appList.length; var length = appList.length;
for (var i = 0; i < length && i < 3; i++) { for (var i = 0; i < length && i < 5; i++) {
var app = appList[i]; var app = appList[i];
appWidgetList.add(Container( appWidgetList.add(Container(
child: MeRouterAppItemComponent(app), child: MeRouterAppItemComponent(app),
@@ -184,18 +197,12 @@ class _MeRouter extends State<MeRouter> {
// TODO add zap send list here! // TODO add zap send list here!
List<Widget> logList = []; List<Widget> logList = [];
logList.add(Container( for (var authLog in authLogs) {
child: MeRouterLogItemComponent(), logList.add(Container(
)); child: MeRouterLogItemComponent(authLog),
logList.add(Divider()); ));
logList.add(Container( logList.add(Divider());
child: MeRouterLogItemComponent(), }
));
logList.add(Divider());
logList.add(Container(
child: MeRouterLogItemComponent(),
));
logList.add(Divider());
logList.add(Container( logList.add(Container(
alignment: Alignment.center, alignment: Alignment.center,
child: Text( child: Text(

View File

@@ -1,7 +1,17 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:nostr_sdk/utils/string_util.dart';
import 'package:nowser/const/auth_result.dart';
import 'package:nowser/const/auth_type.dart';
import 'package:nowser/const/base.dart'; import 'package:nowser/const/base.dart';
import 'package:nowser/data/auth_log.dart';
import 'package:nowser/provider/app_provider.dart';
import 'package:provider/provider.dart';
class MeRouterLogItemComponent extends StatefulWidget { class MeRouterLogItemComponent extends StatefulWidget {
AuthLog authLog;
MeRouterLogItemComponent(this.authLog);
@override @override
State<StatefulWidget> createState() { State<StatefulWidget> createState() {
return _MeRouterLogItemComponent(); return _MeRouterLogItemComponent();
@@ -11,23 +21,80 @@ class MeRouterLogItemComponent extends StatefulWidget {
class _MeRouterLogItemComponent extends State<MeRouterLogItemComponent> { class _MeRouterLogItemComponent extends State<MeRouterLogItemComponent> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
var appProvider = Provider.of<AppProvider>(context);
var app = appProvider.getAppById(widget.authLog.appId!);
var appName = "";
if (app != null) {
if (StringUtil.isNotBlank(app.name)) {
appName = app.name!;
} else if (StringUtil.isNotBlank(app.code)) {
appName = app.code!;
}
}
var appNameWidget = Container( var appNameWidget = Container(
constraints: BoxConstraints(maxWidth: 80), constraints: BoxConstraints(maxWidth: 80),
margin: EdgeInsets.only( margin: EdgeInsets.only(
left: Base.BASE_PADDING_HALF, left: Base.BASE_PADDING_HALF,
right: Base.BASE_PADDING, right: Base.BASE_PADDING_HALF,
), ),
child: Text( child: Text(
"APP Name APP Name", appName,
maxLines: 1, maxLines: 1,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
), ),
); );
late Widget resultWidget;
if (widget.authLog.authResult == AuthResult.OK) {
resultWidget = Card.filled(
color: Colors.green,
child: Container(
padding: EdgeInsets.only(
left: Base.BASE_PADDING_HALF,
right: Base.BASE_PADDING_HALF,
top: 2,
bottom: 2,
),
child: Text(
"approve",
style: TextStyle(color: Colors.white),
),
),
);
} else {
resultWidget = Card.filled(
color: Colors.red,
child: Container(
padding: EdgeInsets.only(
left: Base.BASE_PADDING_HALF,
right: Base.BASE_PADDING_HALF,
),
child: Text(
"reject",
style: TextStyle(color: Colors.white),
),
),
);
}
String authContent = "";
var authType = widget.authLog.authType!;
authContent += AuthType.getAuthName(context, authType);
if (authType == AuthType.SIGN_EVENT) {
authContent += " EventKind(${widget.authLog.eventKind})";
} else if (authType >= AuthType.NIP04_ENCRYPT) {
if (StringUtil.isNotBlank(widget.authLog.content)) {
authContent += widget.authLog.content!;
}
}
var logWidget = Expanded( var logWidget = Expanded(
child: Container( child: Container(
child: Text( child: Text(
"Log Log Log Log Log Log Log Log Log Log Log Log Log Log Log Log", authContent,
maxLines: 1, maxLines: 1,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
), ),
@@ -41,6 +108,10 @@ class _MeRouterLogItemComponent extends State<MeRouterLogItemComponent> {
child: Row( child: Row(
children: [ children: [
appNameWidget, appNameWidget,
Container(
margin: EdgeInsets.only(right: Base.BASE_PADDING_HALF),
child: resultWidget,
),
logWidget, logWidget,
rightIconWidget, rightIconWidget,
], ],