Files
nowser/lib/provider/permission_check_mixin.dart
2025-06-03 18:02:02 +08:00

140 lines
4.3 KiB
Dart

import 'package:flutter/material.dart';
import 'package:nostr_sdk/signer/nostr_signer.dart';
import 'package:nowser/component/auth_dialog/auth_app_connect_dialog.dart';
import 'package:nowser/component/auth_dialog/auth_dialog.dart';
import 'package:nowser/component/user/user_login_dialog.dart';
import 'package:nowser/const/auth_result.dart';
import 'package:nowser/const/reject_type.dart';
import 'package:nowser/data/auth_log.dart';
import 'package:nowser/data/auth_log_db.dart';
import 'package:nowser/main.dart';
import '../const/connect_type.dart';
import '../data/app.dart';
mixin PermissionCheckMixin {
Future<void> checkPermission(
BuildContext? context,
int appType,
String code,
int authType,
Function(App?, int rejectType) reject,
Function(App, NostrSigner) confirm,
{int? eventKind,
String? authDetail}) async {
if (keyProvider.keys.isEmpty) {
// should add a key first
if (context != null) {
await UserLoginDialog.show(context);
}
if (keyProvider.keys.isEmpty) {
return;
}
}
var app = appProvider.getApp(appType, code);
if (app == null) {
// app is null, app connect
var newApp = await getApp(appType, code);
if (context != null) {
await AuthAppConnectDialog.show(context, newApp);
}
// reload from provider
app = appProvider.getApp(appType, code);
}
if (app == null) {
// not allow connect
reject(null, RejectType.OTHERS);
return;
}
var signer = await getSigner(app.pubkey!);
if (signer == null) {
saveAuthLog(app, authType, eventKind, authDetail, AuthResult.REJECT);
reject(app, RejectType.OTHERS);
return;
}
if (app.connectType == ConnectType.FULLY_TRUST) {
try {
confirm(app, signer);
saveAuthLog(app, authType, eventKind, authDetail, AuthResult.OK);
} catch (e) {
print("confirm error $e");
reject(app, RejectType.OTHERS);
saveAuthLog(app, authType, eventKind, authDetail, AuthResult.REJECT);
}
return;
} else if (app.connectType == ConnectType.REASONABLE) {
var permissionCheckResult = appProvider
.checkPermission(appType, code, authType, eventKind: eventKind);
// print("permissionCheckResult $permissionCheckResult");
if (permissionCheckResult == AuthResult.OK) {
try {
confirm(app, signer);
saveAuthLog(app, authType, eventKind, authDetail, AuthResult.OK);
} catch (e) {
print("confirm error $e");
reject(app, RejectType.OTHERS);
saveAuthLog(app, authType, eventKind, authDetail, AuthResult.REJECT);
}
return;
} else if (permissionCheckResult == AuthResult.REJECT) {
saveAuthLog(app, authType, eventKind, authDetail, AuthResult.REJECT);
reject(app, RejectType.REJECT);
return;
}
if (context != null) {
var authResult = await AuthDialog.show(context, app, authType,
eventKind: eventKind, authDetail: authDetail);
if (authResult == AuthResult.OK) {
try {
confirm(app, signer);
saveAuthLog(app, authType, eventKind, authDetail, AuthResult.OK);
} catch (e) {
print("confirm error $e");
reject(app, RejectType.OTHERS);
saveAuthLog(
app, authType, eventKind, authDetail, AuthResult.REJECT);
}
return;
} else if (authResult == AuthResult.REJECT) {
// return reject here ?
}
}
}
saveAuthLog(app, authType, eventKind, authDetail, AuthResult.REJECT);
reject(app, RejectType.OTHERS);
return;
}
void saveAuthLog(App app, int authType, int? eventKind, String? authDetail,
int authResult) {
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
Future<App> getApp(int appType, String code) async {
// TODO name, image
return App(appType: appType, code: code);
}
Future<NostrSigner?> getSigner(String pubkey) {
return keyProvider.getSigner(pubkey);
}
}