diff --git a/flutter/android/app/build.gradle b/flutter/android/app/build.gradle index cf6141c..10a233e 100644 --- a/flutter/android/app/build.gradle +++ b/flutter/android/app/build.gradle @@ -1,5 +1,8 @@ plugins { id "com.android.application" + // START: FlutterFire Configuration + id 'com.google.gms.google-services' + // END: FlutterFire Configuration id "kotlin-android" id "dev.flutter.flutter-gradle-plugin" } @@ -29,7 +32,7 @@ if (keystorePropertiesFile.exists()) { } android { - namespace "com.example.simplecloudnotifier" + namespace "com.blackforestbytes.simplecloudnotifier" compileSdkVersion flutter.compileSdkVersion ndkVersion flutter.ndkVersion diff --git a/flutter/android/app/google-services.json b/flutter/android/app/google-services.json new file mode 100644 index 0000000..772ca40 --- /dev/null +++ b/flutter/android/app/google-services.json @@ -0,0 +1,56 @@ +{ + "project_info": { + "project_number": "232728961679", + "firebase_url": "https://simplecloudnotifier-ea7ef.firebaseio.com", + "project_id": "simplecloudnotifier-ea7ef", + "storage_bucket": "simplecloudnotifier-ea7ef.appspot.com" + }, + "client": [ + { + "client_info": { + "mobilesdk_app_id": "1:232728961679:android:23c75317f79601c9", + "android_client_info": { + "package_name": "com.blackforestbytes.simplecloudnotifier" + } + }, + "oauth_client": [ + { + "client_id": "232728961679-o7gig6f684mp1l1ok7719v3jf3csejc1.apps.googleusercontent.com", + "client_type": 1, + "android_info": { + "package_name": "com.blackforestbytes.simplecloudnotifier", + "certificate_hash": "3bcafbd39256422f0cb51fd446a228c26543afb4" + } + }, + { + "client_id": "232728961679-t1h2eo5keha2lrvhsvdr5kgbkbfkja0o.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyBasR6JLAjM5Ut0rPb0euE_9DdDoTkcvKQ" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [ + { + "client_id": "232728961679-f2951kg24ngsttkhd96qhcr8j3lc8nnk.apps.googleusercontent.com", + "client_type": 3 + }, + { + "client_id": "232728961679-bsbtc6orskaqafc8gtsuqia53f6ree48.apps.googleusercontent.com", + "client_type": 2, + "ios_info": { + "bundle_id": "com.blackforestbytes.SimpleCloudNotifier", + "app_store_id": "6455594868" + } + } + ] + } + } + } + ], + "configuration_version": "1" +} \ No newline at end of file diff --git a/flutter/android/app/src/main/kotlin/com/example/simplecloudnotifier/MainActivity.kt b/flutter/android/app/src/main/kotlin/com/example/simplecloudnotifier/MainActivity.kt index 5affd69..7988bae 100644 --- a/flutter/android/app/src/main/kotlin/com/example/simplecloudnotifier/MainActivity.kt +++ b/flutter/android/app/src/main/kotlin/com/example/simplecloudnotifier/MainActivity.kt @@ -1,6 +1,12 @@ -package com.example.simplecloudnotifier +package com.blackforestbytes.simplecloudnotifier import io.flutter.embedding.android.FlutterActivity class MainActivity: FlutterActivity() { + onCreate() { + GoogleApiAvailability.makeGooglePlayServicesAvailable() + } + onResume() { + GoogleApiAvailability.makeGooglePlayServicesAvailable() + } } diff --git a/flutter/android/settings.gradle b/flutter/android/settings.gradle index 7cd7128..495528e 100644 --- a/flutter/android/settings.gradle +++ b/flutter/android/settings.gradle @@ -24,6 +24,9 @@ pluginManagement { plugins { id "dev.flutter.flutter-plugin-loader" version "1.0.0" id "com.android.application" version "7.3.0" apply false + // START: FlutterFire Configuration + id "com.google.gms.google-services" version "4.3.15" apply false + // END: FlutterFire Configuration } include ":app" diff --git a/flutter/firebase.json b/flutter/firebase.json new file mode 100644 index 0000000..5640cbe --- /dev/null +++ b/flutter/firebase.json @@ -0,0 +1,25 @@ +{ + "flutter":{ + "platforms":{ + "android":{ + "default":{ + "projectId":"simplecloudnotifier-ea7ef", + "appId":"1:232728961679:android:23c75317f79601c9", + "fileOutput":"android/app/google-services.json" + } + }, + "dart":{ + "lib/firebase_options.dart":{ + "projectId":"simplecloudnotifier-ea7ef", + "configurations":{ + "android":"1:232728961679:android:23c75317f79601c9", + "ios":"1:232728961679:ios:85155ba52c4f3311b446fa", + "macos":"1:232728961679:ios:85155ba52c4f3311b446fa", + "web":"1:232728961679:web:e53211fff778ab61b446fa", + "windows":"1:232728961679:web:6e8235651da6241eb446fa" + } + } + } + } + } +} \ No newline at end of file diff --git a/flutter/firepit-log.txt b/flutter/firepit-log.txt new file mode 100644 index 0000000..a53466d --- /dev/null +++ b/flutter/firepit-log.txt @@ -0,0 +1,13 @@ +Welcome to firepit v1.1.0! +Doing JSON parses for version checks at /snapshot/firepit/vendor/node_modules/firebase-tools/package.json +is-ci,mime,rc,rimraf,yaml,abbrev,abort-controller,accepts,agent-base,aggregate-error,ajv,ajv-formats,ansi-align,ansi-escapes,ansi-regex,ansi-styles,ansicolors,anymatch,archiver,archiver-utils,argparse,array-flatten,arrify,as-array,ast-types,async,async-lock,asynckit,balanced-match,base64-js,basic-auth,basic-auth-connect,basic-ftp,bignumber.js,binary-extensions,bl,body-parser,boxen,brace-expansion,braces,buffer,buffer-crc32,buffer-equal-constant-time,bytes,cacache,call-bind,call-me-maybe,camelcase,cardinal,chalk,chardet,chokidar,chownr,ci-info,cjson,clean-stack,cli-boxes,cli-cursor,cli-spinners,cli-table,cli-table3,cli-width,cliui,clone,color,color-convert,color-name,color-string,colorette,colors,colorspace,combined-stream,commander,compress-commons,compressible,compression,concat-map,config-chain,configstore,connect,content-disposition,content-type,cookie,cookie-signature,core-util-is,cors,crc-32,crc32-stream,cross-env,cross-spawn,crypto-random-string,csv-parse,data-uri-to-buffer,debug,deep-equal-in-any-order,deep-extend,deep-freeze,deep-is,defaults,define-data-property,degenerator,delayed-stream,depd,destroy,discontinuous-range,dot-prop,duplexify,eastasianwidth,ecdsa-sig-formatter,ee-first,emoji-regex,enabled,encodeurl,encoding,end-of-stream,env-paths,err-code,es-define-property,es-errors,escalade,escape-goat,escape-html,escape-string-regexp,escodegen,esprima,estraverse,esutils,etag,event-target-shim,events-listener,exegesis,exegesis-express,exponential-backoff,express,extend,external-editor,fast-deep-equal,fast-json-stable-stringify,fast-url-parser,fecha,figures,filesize,fill-range,finalhandler,firebase-tools,fn.name,foreground-child,form-data,forwarded,fresh,fs-constants,fs-extra,fs-minipass,fs.realpath,function-bind,fuzzy,gaxios,gcp-metadata,get-caller-file,get-intrinsic,get-stdin,get-uri,glob,glob-parent,glob-slash,glob-slasher,global-dirs,google-auth-library,google-gax,googleapis-common,gopd,graceful-fs,gtoken,has-flag,has-property-descriptors,has-proto,has-symbols,has-yarn,hasown,heap-js,http-cache-semantics,http-errors,http-proxy-agent,https-proxy-agent,iconv-lite,ieee754,import-lazy,imurmurhash,indent-string,inflight,inherits,ini,inquirer,inquirer-autocomplete-prompt,install-artifact-from-github,ip-address,ip-regex,ipaddr.js,is-arrayish,is-binary-path,is-extglob,is-fullwidth-code-point,is-glob,is-installed-globally,is-interactive,is-lambda,is-npm,is-number,is-obj,is-path-inside,is-stream,is-stream-ended,is-typedarray,is-unicode-supported,is-url,is-wsl,is-yarn-global,is2,isarray,isexe,isomorphic-fetch,jackspeak,jju,join-path,js-yaml,jsbn,json-bigint,json-parse-helpfulerror,json-ptr,json-schema-traverse,jsonfile,jsonwebtoken,jwa,jws,kuler,lazystream,leven,libsodium,libsodium-wrappers,lodash,lodash._objecttypes,lodash.camelcase,lodash.defaults,lodash.difference,lodash.flatten,lodash.includes,lodash.isboolean,lodash.isinteger,lodash.isnumber,lodash.isobject,lodash.isplainobject,lodash.isstring,lodash.mapvalues,lodash.once,lodash.snakecase,lodash.union,log-symbols,logform,long,lru-cache,make-dir,make-fetch-happen,marked,marked-terminal,media-typer,merge-descriptors,methods,mime-db,mime-types,mimic-fn,minimatch,minimist,minipass,minipass-collect,minipass-fetch,minipass-flush,minipass-pipeline,minipass-sized,minizlib,mkdirp,moo,morgan,ms,mute-stream,nan,nearley,negotiator,netmask,nice-try,node-emoji,node-fetch,node-gyp,nopt,normalize-path,object-assign,object-hash,object-inspect,on-finished,on-headers,once,one-time,onetime,open,openapi3-ts,ora,os-tmpdir,p-defer,p-limit,p-map,p-throttle,pac-proxy-agent,pac-resolver,parseurl,path-is-absolute,path-key,path-scurry,path-to-regexp,pg,pg-cloudflare,pg-connection-string,pg-int8,pg-pool,pg-protocol,pg-types,pgpass,picocolors,picomatch,portfinder,postgres-array,postgres-bytea,postgres-date,postgres-interval,proc-log,process-nextick-args,progress,promise-breaker,promise-retry,proto-list,proto3-json-serializer,protobufjs,proxy-addr,proxy-agent,proxy-from-env,pump,punycode,pupa,qs,railroad-diagrams,randexp,range-parser,raw-body,re2,readable-stream,readdir-glob,readdirp,redeyed,registry-auth-token,registry-url,require-directory,require-from-string,restore-cursor,ret,retry,retry-request,router,run-async,rxjs,safe-buffer,safe-stable-stringify,safer-buffer,semver,semver-diff,send,serve-static,set-function-length,setprototypeof,shebang-command,shebang-regex,side-channel,signal-exit,simple-swizzle,smart-buffer,socks,socks-proxy-agent,sort-any,source-map,split2,sprintf-js,sql-formatter,ssri,stack-trace,statuses,stream-chain,stream-events,stream-json,stream-shift,string-width,string-width-cjs,string_decoder,strip-ansi,strip-ansi-cjs,strip-json-comments,stubs,superstatic,supports-color,supports-hyperlinks,tar,tar-stream,tcp-port-used,teeny-request,text-hex,through,tmp,to-regex-range,toidentifier,toxic,tr46,triple-beam,tslib,type-fest,type-is,typedarray-to-buffer,undici-types,unique-filename,unique-slug,unique-string,universal-analytics,universalify,unpipe,update-notifier-cjs,uri-js,url-join,url-template,util-deprecate,utils-merge,uuid,valid-url,vary,wcwidth,webidl-conversions,whatwg-fetch,whatwg-url,which,widest-line,winston,winston-transport,wrap-ansi,wrap-ansi-cjs,wrappy,write-file-atomic,ws,xdg-basedir,xtend,y18n,yallist,yargs,yargs-parser,yocto-queue,zip-stream,@apidevtools,@colors,@dabh,@google-cloud,@googleapis,@grpc,@isaacs,@js-sdsl,@jsdevtools,@npmcli,@opentelemetry,@pkgjs,@pnpm,@protobufjs,@tootallnate,@types +Installed ft@13.10.2 and packaged ft@13.10.2 +Checking for npm/bin/npm-cli install at /home/mike/.cache/firebase/tools/lib/node_modules/npm/bin/npm-cli +Checking for npm/bin/npm-cli install at /home/mike/.cache/firebase/tools/node_modules/npm/bin/npm-cli +Checking for npm/bin/npm-cli install at /snapshot/firepit/node_modules/npm/bin/npm-cli +Found npm/bin/npm-cli install. +Checking for npm/bin/npm-cli install at /home/mike/.cache/firebase/tools/lib/node_modules/npm/bin/npm-cli +Checking for npm/bin/npm-cli install at /home/mike/.cache/firebase/tools/node_modules/npm/bin/npm-cli +Checking for npm/bin/npm-cli install at /snapshot/firepit/node_modules/npm/bin/npm-cli +Found npm/bin/npm-cli install. +ShellJSInternalError: ENOENT: no such file or directory, chmod '/home/mike/.cache/firebase/runtime/shell' \ No newline at end of file diff --git a/flutter/ios/Runner.xcodeproj/project.pbxproj b/flutter/ios/Runner.xcodeproj/project.pbxproj index f346daf..224d234 100644 --- a/flutter/ios/Runner.xcodeproj/project.pbxproj +++ b/flutter/ios/Runner.xcodeproj/project.pbxproj @@ -367,7 +367,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = com.example.simplecloudnotifier; + PRODUCT_BUNDLE_IDENTIFIER = com.blackforestbytes.simplecloudnotifier; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_VERSION = 5.0; @@ -384,7 +384,7 @@ CURRENT_PROJECT_VERSION = 1; GENERATE_INFOPLIST_FILE = YES; MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = com.example.simplecloudnotifier.RunnerTests; + PRODUCT_BUNDLE_IDENTIFIER = com.blackforestbytes.simplecloudnotifier.RunnerTests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; @@ -402,7 +402,7 @@ CURRENT_PROJECT_VERSION = 1; GENERATE_INFOPLIST_FILE = YES; MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = com.example.simplecloudnotifier.RunnerTests; + PRODUCT_BUNDLE_IDENTIFIER = com.blackforestbytes.simplecloudnotifier.RunnerTests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; @@ -418,7 +418,7 @@ CURRENT_PROJECT_VERSION = 1; GENERATE_INFOPLIST_FILE = YES; MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = com.example.simplecloudnotifier.RunnerTests; + PRODUCT_BUNDLE_IDENTIFIER = com.blackforestbytes.simplecloudnotifier.RunnerTests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; @@ -545,7 +545,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = com.example.simplecloudnotifier; + PRODUCT_BUNDLE_IDENTIFIER = com.blackforestbytes.simplecloudnotifier; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; @@ -567,7 +567,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = com.example.simplecloudnotifier; + PRODUCT_BUNDLE_IDENTIFIER = com.blackforestbytes.simplecloudnotifier; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_VERSION = 5.0; diff --git a/flutter/lib/api/api_client.dart b/flutter/lib/api/api_client.dart index 0d0a664..934b0c6 100644 --- a/flutter/lib/api/api_client.dart +++ b/flutter/lib/api/api_client.dart @@ -138,6 +138,37 @@ class APIClient { ); } + static Future addClient(KeyTokenAuth? auth, String fcmToken, String agentModel, String agentVersion, String clientType) async { + return await _request( + name: 'addClient', + method: 'POST', + relURL: 'users/${auth!.userId}/clients', + jsonBody: { + 'fcm_token': fcmToken, + 'agent_model': agentModel, + 'agent_version': agentVersion, + 'client_type': clientType, + }, + fn: Client.fromJson, + auth: auth, + ); + } + + static Future updateClient(KeyTokenAuth? auth, String clientID, String fcmToken, String agentModel, String agentVersion) async { + return await _request( + name: 'updateClient', + method: 'PUT', + relURL: 'users/${auth!.userId}/clients/$clientID', + jsonBody: { + 'fcm_token': fcmToken, + 'agent_model': agentModel, + 'agent_version': agentVersion, + }, + fn: Client.fromJson, + auth: auth, + ); + } + static Future> getChannelList(KeyTokenAuth auth, ChannelSelector sel) async { return await _request( name: 'getChannelList', diff --git a/flutter/lib/firebase_options.dart b/flutter/lib/firebase_options.dart new file mode 100644 index 0000000..47e55e1 --- /dev/null +++ b/flutter/lib/firebase_options.dart @@ -0,0 +1,94 @@ +// File generated by FlutterFire CLI. +// ignore_for_file: type=lint +import 'package:firebase_core/firebase_core.dart' show FirebaseOptions; +import 'package:flutter/foundation.dart' + show defaultTargetPlatform, kIsWeb, TargetPlatform; + +/// Default [FirebaseOptions] for use with your Firebase apps. +/// +/// Example: +/// ```dart +/// import 'firebase_options.dart'; +/// // ... +/// await Firebase.initializeApp( +/// options: DefaultFirebaseOptions.currentPlatform, +/// ); +/// ``` +class DefaultFirebaseOptions { + static FirebaseOptions get currentPlatform { + if (kIsWeb) { + return web; + } + switch (defaultTargetPlatform) { + case TargetPlatform.android: + return android; + case TargetPlatform.iOS: + return ios; + case TargetPlatform.macOS: + return macos; + case TargetPlatform.windows: + return windows; + case TargetPlatform.linux: + throw UnsupportedError( + 'DefaultFirebaseOptions have not been configured for linux - ' + 'you can reconfigure this by running the FlutterFire CLI again.', + ); + default: + throw UnsupportedError( + 'DefaultFirebaseOptions are not supported for this platform.', + ); + } + } + + static const FirebaseOptions web = FirebaseOptions( + apiKey: 'AIzaSyCbA3VPKlkfJXw27L_J1x5VbfxeqmjdR5o', + appId: '1:232728961679:web:e53211fff778ab61b446fa', + messagingSenderId: '232728961679', + projectId: 'simplecloudnotifier-ea7ef', + authDomain: 'simplecloudnotifier-ea7ef.firebaseapp.com', + databaseURL: 'https://simplecloudnotifier-ea7ef.firebaseio.com', + storageBucket: 'simplecloudnotifier-ea7ef.appspot.com', + ); + + static const FirebaseOptions android = FirebaseOptions( + apiKey: 'AIzaSyBasR6JLAjM5Ut0rPb0euE_9DdDoTkcvKQ', + appId: '1:232728961679:android:23c75317f79601c9', + messagingSenderId: '232728961679', + projectId: 'simplecloudnotifier-ea7ef', + databaseURL: 'https://simplecloudnotifier-ea7ef.firebaseio.com', + storageBucket: 'simplecloudnotifier-ea7ef.appspot.com', + ); + + static const FirebaseOptions ios = FirebaseOptions( + apiKey: 'AIzaSyCJpUsV4ApJfQPcSDpPj2CkzNyS8093A8s', + appId: '1:232728961679:ios:85155ba52c4f3311b446fa', + messagingSenderId: '232728961679', + projectId: 'simplecloudnotifier-ea7ef', + databaseURL: 'https://simplecloudnotifier-ea7ef.firebaseio.com', + storageBucket: 'simplecloudnotifier-ea7ef.appspot.com', + androidClientId: '232728961679-o7gig6f684mp1l1ok7719v3jf3csejc1.apps.googleusercontent.com', + iosBundleId: 'com.blackforestbytes.simplecloudnotifier', + ); + + static const FirebaseOptions macos = FirebaseOptions( + apiKey: 'AIzaSyCJpUsV4ApJfQPcSDpPj2CkzNyS8093A8s', + appId: '1:232728961679:ios:85155ba52c4f3311b446fa', + messagingSenderId: '232728961679', + projectId: 'simplecloudnotifier-ea7ef', + databaseURL: 'https://simplecloudnotifier-ea7ef.firebaseio.com', + storageBucket: 'simplecloudnotifier-ea7ef.appspot.com', + androidClientId: '232728961679-o7gig6f684mp1l1ok7719v3jf3csejc1.apps.googleusercontent.com', + iosBundleId: 'com.blackforestbytes.simplecloudnotifier', + ); + + static const FirebaseOptions windows = FirebaseOptions( + apiKey: 'AIzaSyCbA3VPKlkfJXw27L_J1x5VbfxeqmjdR5o', + appId: '1:232728961679:web:6e8235651da6241eb446fa', + messagingSenderId: '232728961679', + projectId: 'simplecloudnotifier-ea7ef', + authDomain: 'simplecloudnotifier-ea7ef.firebaseapp.com', + databaseURL: 'https://simplecloudnotifier-ea7ef.firebaseio.com', + storageBucket: 'simplecloudnotifier-ea7ef.appspot.com', + ); + +} \ No newline at end of file diff --git a/flutter/lib/main.dart b/flutter/lib/main.dart index 68897e8..0c40ff3 100644 --- a/flutter/lib/main.dart +++ b/flutter/lib/main.dart @@ -1,13 +1,17 @@ +import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:fl_toast/fl_toast.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:hive_flutter/hive_flutter.dart'; +import 'package:simplecloudnotifier/api/api_client.dart'; import 'package:simplecloudnotifier/nav_layout.dart'; import 'package:simplecloudnotifier/state/app_theme.dart'; import 'package:simplecloudnotifier/state/application_log.dart'; import 'package:simplecloudnotifier/state/globals.dart'; import 'package:simplecloudnotifier/state/request_log.dart'; import 'package:simplecloudnotifier/state/user_account.dart'; +import 'package:firebase_core/firebase_core.dart'; +import 'firebase_options.dart'; void main() async { WidgetsFlutterBinding.ensureInitialized(); @@ -35,6 +39,22 @@ void main() async { ApplicationLog.error('Failed to open Hive-Box: scn-logs: ' + exc.toString(), trace: trace); } + UserAccount(); // ensure UserAccount is loaded + + await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform); + + final notificationSettings = await FirebaseMessaging.instance.requestPermission(provisional: true); + + FirebaseMessaging.instance.onTokenRefresh.listen((fcmToken) { + try { + setFirebaseToken(fcmToken); + } catch (exc, trace) { + ApplicationLog.error('Failed to set firebase token: ' + exc.toString(), trace: trace); + } + }).onError((dynamic err) { + ApplicationLog.error('Failed to listen to token refresh events: ' + (err?.toString() ?? '')); + }); + ApplicationLog.debug('Application started'); runApp( @@ -48,13 +68,25 @@ void main() async { ); } +void setFirebaseToken(String fcmToken) async { + ApplicationLog.info('New firebase token: $fcmToken'); + final acc = UserAccount(); + if (acc.auth != null) { + if (acc.client == null) { + final client = await APIClient.addClient(acc.auth, fcmToken, Globals().platform, Globals().version, Globals().clientType); + acc.setClient(client); + } else { + final client = await APIClient.updateClient(acc.auth, acc.client!.clientID, fcmToken, Globals().platform, Globals().version); + acc.setClient(client); + } + } +} + class SCNApp extends StatelessWidget { const SCNApp({super.key}); @override Widget build(BuildContext context) { - Provider.of(context); // ensure UserAccount is loaded (unneccessary if lazy: false is set in MultiProvider ??) - return Consumer( builder: (context, appTheme, child) => MaterialApp( title: 'SimpleCloudNotifier', diff --git a/flutter/lib/state/globals.dart b/flutter/lib/state/globals.dart index 583b190..063ef81 100644 --- a/flutter/lib/state/globals.dart +++ b/flutter/lib/state/globals.dart @@ -1,5 +1,6 @@ import 'dart:io'; +import 'package:device_info_plus/device_info_plus.dart'; import 'package:package_info_plus/package_info_plus.dart'; import 'package:shared_preferences/shared_preferences.dart'; @@ -18,6 +19,8 @@ class Globals { String buildNumber = ''; String platform = ''; String hostname = ''; + String clientType = ''; + String deviceModel = ''; late SharedPreferences sharedPrefs; @@ -31,6 +34,25 @@ class Globals { this.platform = Platform.operatingSystem; this.hostname = Platform.localHostname; + if (Platform.isAndroid) { + this.clientType = 'ANDROID'; + this.deviceModel = (await DeviceInfoPlugin().androidInfo).model; + } else if (Platform.isIOS) { + this.clientType = 'IOS'; + this.deviceModel = (await DeviceInfoPlugin().iosInfo).model; + } else if (Platform.isLinux) { + this.clientType = 'LINUX'; + this.deviceModel = (await DeviceInfoPlugin().linuxInfo).prettyName; + } else if (Platform.isWindows) { + this.clientType = 'WINDOWS'; + this.deviceModel = (await DeviceInfoPlugin().windowsInfo).productName; + } else if (Platform.isMacOS) { + this.clientType = 'MACOS'; + this.deviceModel = (await DeviceInfoPlugin().macOsInfo).model; + } else { + this.clientType = '?'; + } + this.sharedPrefs = await SharedPreferences.getInstance(); } } diff --git a/flutter/lib/state/user_account.dart b/flutter/lib/state/user_account.dart index cf71ab4..8cf8c26 100644 --- a/flutter/lib/state/user_account.dart +++ b/flutter/lib/state/user_account.dart @@ -1,6 +1,7 @@ import 'package:flutter/foundation.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:simplecloudnotifier/api/api_client.dart'; +import 'package:simplecloudnotifier/models/client.dart'; import 'package:simplecloudnotifier/models/key_token_auth.dart'; import 'package:simplecloudnotifier/models/user.dart'; import 'package:simplecloudnotifier/state/globals.dart'; @@ -9,10 +10,19 @@ class UserAccount extends ChangeNotifier { User? _user; User? get user => _user; + Client? _client; + Client? get client => _client; + KeyTokenAuth? _auth; KeyTokenAuth? get auth => _auth; - UserAccount() { + static UserAccount? _singleton = UserAccount._internal(); + + factory UserAccount() { + return _singleton ?? (_singleton = UserAccount._internal()); + } + + UserAccount._internal() { load(); } @@ -38,6 +48,16 @@ class UserAccount extends ChangeNotifier { notifyListeners(); } + void setClient(Client client) { + _client = client; + notifyListeners(); + } + + void clearClient() { + _client = null; + notifyListeners(); + } + void load() { final uid = Globals().sharedPrefs.getString('auth.userid'); final tok = Globals().sharedPrefs.getString('auth.token'); diff --git a/flutter/linux/CMakeLists.txt b/flutter/linux/CMakeLists.txt index b7d7fa0..179adbe 100644 --- a/flutter/linux/CMakeLists.txt +++ b/flutter/linux/CMakeLists.txt @@ -7,7 +7,7 @@ project(runner LANGUAGES CXX) set(BINARY_NAME "simplecloudnotifier") # The unique GTK application identifier for this application. See: # https://wiki.gnome.org/HowDoI/ChooseApplicationID -set(APPLICATION_ID "com.example.simplecloudnotifier") +set(APPLICATION_ID "com.blackforestbytes.simplecloudnotifier") # Explicitly opt in to modern CMake behaviors to avoid warnings with recent # versions of CMake. diff --git a/flutter/macos/Flutter/GeneratedPluginRegistrant.swift b/flutter/macos/Flutter/GeneratedPluginRegistrant.swift index 9506405..05dd87d 100644 --- a/flutter/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/flutter/macos/Flutter/GeneratedPluginRegistrant.swift @@ -5,12 +5,18 @@ import FlutterMacOS import Foundation +import device_info_plus +import firebase_core +import firebase_messaging import package_info_plus import path_provider_foundation import shared_preferences_foundation import url_launcher_macos func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { + DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin")) + FLTFirebaseCorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCorePlugin")) + FLTFirebaseMessagingPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseMessagingPlugin")) FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin")) PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) diff --git a/flutter/macos/Runner.xcodeproj/project.pbxproj b/flutter/macos/Runner.xcodeproj/project.pbxproj index 882b5e8..5ce128d 100644 --- a/flutter/macos/Runner.xcodeproj/project.pbxproj +++ b/flutter/macos/Runner.xcodeproj/project.pbxproj @@ -384,7 +384,7 @@ CURRENT_PROJECT_VERSION = 1; GENERATE_INFOPLIST_FILE = YES; MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = com.example.simplecloudnotifier.RunnerTests; + PRODUCT_BUNDLE_IDENTIFIER = com.blackforestbytes.simplecloudnotifier.RunnerTests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/simplecloudnotifier.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/simplecloudnotifier"; @@ -398,7 +398,7 @@ CURRENT_PROJECT_VERSION = 1; GENERATE_INFOPLIST_FILE = YES; MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = com.example.simplecloudnotifier.RunnerTests; + PRODUCT_BUNDLE_IDENTIFIER = com.blackforestbytes.simplecloudnotifier.RunnerTests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/simplecloudnotifier.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/simplecloudnotifier"; @@ -412,7 +412,7 @@ CURRENT_PROJECT_VERSION = 1; GENERATE_INFOPLIST_FILE = YES; MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = com.example.simplecloudnotifier.RunnerTests; + PRODUCT_BUNDLE_IDENTIFIER = com.blackforestbytes.simplecloudnotifier.RunnerTests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/simplecloudnotifier.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/simplecloudnotifier"; diff --git a/flutter/macos/Runner/Configs/AppInfo.xcconfig b/flutter/macos/Runner/Configs/AppInfo.xcconfig index a5f6b48..dde7eb3 100644 --- a/flutter/macos/Runner/Configs/AppInfo.xcconfig +++ b/flutter/macos/Runner/Configs/AppInfo.xcconfig @@ -8,7 +8,7 @@ PRODUCT_NAME = simplecloudnotifier // The application's bundle identifier -PRODUCT_BUNDLE_IDENTIFIER = com.example.simplecloudnotifier +PRODUCT_BUNDLE_IDENTIFIER = com.blackforestbytes.simplecloudnotifier // The copyright displayed in application information -PRODUCT_COPYRIGHT = Copyright © 2024 com.example. All rights reserved. +PRODUCT_COPYRIGHT = Copyright © 2024 blackforestbytes. All rights reserved. diff --git a/flutter/pubspec.lock b/flutter/pubspec.lock index 70d3d03..ba3da36 100644 --- a/flutter/pubspec.lock +++ b/flutter/pubspec.lock @@ -9,6 +9,14 @@ packages: url: "https://pub.dev" source: hosted version: "67.0.0" + _flutterfire_internals: + dependency: transitive + description: + name: _flutterfire_internals + sha256: "37a42d06068e2fe3deddb2da079a8c4d105f241225ba27b7122b37e9865fd8f7" + url: "https://pub.dev" + source: hosted + version: "1.3.35" analyzer: dependency: transitive description: @@ -177,6 +185,22 @@ packages: url: "https://pub.dev" source: hosted version: "2.3.6" + device_info_plus: + dependency: "direct main" + description: + name: device_info_plus + sha256: eead12d1a1ed83d8283ab4c2f3fca23ac4082f29f25f29dff0f758f57d06ec91 + url: "https://pub.dev" + source: hosted + version: "10.1.0" + device_info_plus_platform_interface: + dependency: transitive + description: + name: device_info_plus_platform_interface + sha256: d3b01d5868b50ae571cd1dc6e502fc94d956b665756180f7b16ead09e836fd64 + url: "https://pub.dev" + source: hosted + version: "7.0.0" fake_async: dependency: transitive description: @@ -201,6 +225,54 @@ packages: url: "https://pub.dev" source: hosted version: "7.0.0" + firebase_core: + dependency: "direct main" + description: + name: firebase_core + sha256: "26de145bb9688a90962faec6f838247377b0b0d32cc0abecd9a4e43525fc856c" + url: "https://pub.dev" + source: hosted + version: "2.32.0" + firebase_core_platform_interface: + dependency: transitive + description: + name: firebase_core_platform_interface + sha256: c437ae5d17e6b5cc7981cf6fd458a5db4d12979905f9aafd1fea930428a9fe63 + url: "https://pub.dev" + source: hosted + version: "5.0.0" + firebase_core_web: + dependency: transitive + description: + name: firebase_core_web + sha256: "43d9e951ac52b87ae9cc38ecdcca1e8fa7b52a1dd26a96085ba41ce5108db8e9" + url: "https://pub.dev" + source: hosted + version: "2.17.0" + firebase_messaging: + dependency: "direct main" + description: + name: firebase_messaging + sha256: a1662cc95d9750a324ad9df349b873360af6f11414902021f130c68ec02267c4 + url: "https://pub.dev" + source: hosted + version: "14.9.4" + firebase_messaging_platform_interface: + dependency: transitive + description: + name: firebase_messaging_platform_interface + sha256: "87c4a922cb6f811cfb7a889bdbb3622702443c52a0271636cbc90d813ceac147" + url: "https://pub.dev" + source: hosted + version: "4.5.37" + firebase_messaging_web: + dependency: transitive + description: + name: firebase_messaging_web + sha256: "0d34dca01a7b103ed7f20138bffbb28eb0e61a677bf9e78a028a932e2c7322d5" + url: "https://pub.dev" + source: hosted + version: "3.8.7" fixnum: dependency: transitive description: @@ -884,6 +956,14 @@ packages: url: "https://pub.dev" source: hosted version: "5.5.0" + win32_registry: + dependency: transitive + description: + name: win32_registry + sha256: "10589e0d7f4e053f2c61023a31c9ce01146656a70b7b7f0828c0b46d7da2a9bb" + url: "https://pub.dev" + source: hosted + version: "1.1.3" xdg_directories: dependency: transitive description: diff --git a/flutter/pubspec.yaml b/flutter/pubspec.yaml index 25956c0..7ba43b1 100644 --- a/flutter/pubspec.yaml +++ b/flutter/pubspec.yaml @@ -26,6 +26,9 @@ dependencies: fl_toast: ^3.2.0 xid: ^1.2.1 flutter_lazy_indexed_stack: ^0.0.6 + firebase_core: ^2.32.0 + firebase_messaging: ^14.9.4 + device_info_plus: ^10.1.0 dependency_overrides: diff --git a/flutter/windows/flutter/generated_plugin_registrant.cc b/flutter/windows/flutter/generated_plugin_registrant.cc index 4f78848..ec8e8d4 100644 --- a/flutter/windows/flutter/generated_plugin_registrant.cc +++ b/flutter/windows/flutter/generated_plugin_registrant.cc @@ -6,9 +6,12 @@ #include "generated_plugin_registrant.h" +#include #include void RegisterPlugins(flutter::PluginRegistry* registry) { + FirebaseCorePluginCApiRegisterWithRegistrar( + registry->GetRegistrarForPlugin("FirebaseCorePluginCApi")); UrlLauncherWindowsRegisterWithRegistrar( registry->GetRegistrarForPlugin("UrlLauncherWindows")); } diff --git a/flutter/windows/flutter/generated_plugins.cmake b/flutter/windows/flutter/generated_plugins.cmake index 88b22e5..02d26c3 100644 --- a/flutter/windows/flutter/generated_plugins.cmake +++ b/flutter/windows/flutter/generated_plugins.cmake @@ -3,6 +3,7 @@ # list(APPEND FLUTTER_PLUGIN_LIST + firebase_core url_launcher_windows ) diff --git a/flutter/windows/runner/Runner.rc b/flutter/windows/runner/Runner.rc index 680414c..ea3e347 100644 --- a/flutter/windows/runner/Runner.rc +++ b/flutter/windows/runner/Runner.rc @@ -89,11 +89,11 @@ BEGIN BEGIN BLOCK "040904e4" BEGIN - VALUE "CompanyName", "com.example" "\0" + VALUE "CompanyName", "blackforestbytes" "\0" VALUE "FileDescription", "simplecloudnotifier" "\0" VALUE "FileVersion", VERSION_AS_STRING "\0" VALUE "InternalName", "simplecloudnotifier" "\0" - VALUE "LegalCopyright", "Copyright (C) 2024 com.example. All rights reserved." "\0" + VALUE "LegalCopyright", "Copyright (C) 2024 blackforestbytes. All rights reserved." "\0" VALUE "OriginalFilename", "simplecloudnotifier.exe" "\0" VALUE "ProductName", "simplecloudnotifier" "\0" VALUE "ProductVersion", VERSION_AS_STRING "\0" diff --git a/scnserver/_gen/enum-generate.go b/scnserver/_gen/enum-generate.go index bd65879..5ec87e9 100644 --- a/scnserver/_gen/enum-generate.go +++ b/scnserver/_gen/enum-generate.go @@ -13,9 +13,8 @@ func main() { panic(err) } - err = bfcodegen.GenerateEnumSpecs(wd, dest) + err = bfcodegen.GenerateEnumSpecs(wd, dest, bfcodegen.EnumGenOptions{}) if err != nil { panic(err) } } - diff --git a/scnserver/_gen/id-generate.go b/scnserver/_gen/id-generate.go index 45e40cd..e56161d 100644 --- a/scnserver/_gen/id-generate.go +++ b/scnserver/_gen/id-generate.go @@ -13,7 +13,7 @@ func main() { panic(err) } - err = bfcodegen.GenerateCharsetIDSpecs(wd, dest) + err = bfcodegen.GenerateCharsetIDSpecs(wd, dest, bfcodegen.CSIDGenOptions{}) if err != nil { panic(err) } diff --git a/scnserver/api/handler/apiClient.go b/scnserver/api/handler/apiClient.go index cd621a9..506df06 100644 --- a/scnserver/api/handler/apiClient.go +++ b/scnserver/api/handler/apiClient.go @@ -119,10 +119,10 @@ func (h APIHandler) AddClient(g *gin.Context) ginresp.HTTPResponse { UserID models.UserID `uri:"uid" binding:"entityid"` } type body struct { - FCMToken string `json:"fcm_token" binding:"required"` - AgentModel string `json:"agent_model" binding:"required"` - AgentVersion string `json:"agent_version" binding:"required"` - ClientType string `json:"client_type" binding:"required"` + FCMToken string `json:"fcm_token" binding:"required"` + AgentModel string `json:"agent_model" binding:"required"` + AgentVersion string `json:"agent_version" binding:"required"` + ClientType models.ClientType `json:"client_type" binding:"required"` } var u uri @@ -133,14 +133,10 @@ func (h APIHandler) AddClient(g *gin.Context) ginresp.HTTPResponse { } defer ctx.Cancel() - var clientType models.ClientType - if b.ClientType == string(models.ClientTypeAndroid) { - clientType = models.ClientTypeAndroid - } else if b.ClientType == string(models.ClientTypeIOS) { - clientType = models.ClientTypeIOS - } else { + if !b.ClientType.Valid() { return ginresp.APIError(g, 400, apierr.INVALID_CLIENTTYPE, "Invalid ClientType", nil) } + clientType := b.ClientType if permResp := ctx.CheckPermissionUserAdmin(u.UserID); permResp != nil { return *permResp diff --git a/scnserver/api/handler/apiUser.go b/scnserver/api/handler/apiUser.go index e4f88f7..39c1703 100644 --- a/scnserver/api/handler/apiUser.go +++ b/scnserver/api/handler/apiUser.go @@ -28,13 +28,13 @@ import ( // @Router /api/v2/users [POST] func (h APIHandler) CreateUser(g *gin.Context) ginresp.HTTPResponse { type body struct { - FCMToken string `json:"fcm_token"` - ProToken *string `json:"pro_token"` - Username *string `json:"username"` - AgentModel string `json:"agent_model"` - AgentVersion string `json:"agent_version"` - ClientType string `json:"client_type"` - NoClient bool `json:"no_client"` + FCMToken string `json:"fcm_token"` + ProToken *string `json:"pro_token"` + Username *string `json:"username"` + AgentModel string `json:"agent_model"` + AgentVersion string `json:"agent_version"` + ClientType models.ClientType `json:"client_type"` + NoClient bool `json:"no_client"` } var b body @@ -55,13 +55,10 @@ func (h APIHandler) CreateUser(g *gin.Context) ginresp.HTTPResponse { if b.ClientType == "" { return ginresp.APIError(g, 400, apierr.INVALID_CLIENTTYPE, "Missing ClientType", nil) } - if b.ClientType == string(models.ClientTypeAndroid) { - clientType = models.ClientTypeAndroid - } else if b.ClientType == string(models.ClientTypeIOS) { - clientType = models.ClientTypeIOS - } else { + if !b.ClientType.Valid() { return ginresp.APIError(g, 400, apierr.BINDFAIL_BODY_PARAM, "Invalid ClientType", nil) } + clientType = b.ClientType } if b.ProToken != nil { diff --git a/scnserver/go.mod b/scnserver/go.mod index 4c71236..c5d28ea 100644 --- a/scnserver/go.mod +++ b/scnserver/go.mod @@ -1,46 +1,58 @@ module blackforestbytes.com/simplecloudnotifier -go 1.19 +go 1.22 + +toolchain go1.22.3 require ( - github.com/gin-gonic/gin v1.9.1 - github.com/go-playground/validator/v10 v10.15.5 - github.com/go-sql-driver/mysql v1.7.1 - github.com/jmoiron/sqlx v1.3.5 - github.com/mattn/go-sqlite3 v1.14.17 - github.com/rs/zerolog v1.31.0 - gogs.mikescher.com/BlackForestBytes/goext v0.0.291 + github.com/gin-gonic/gin v1.10.0 + github.com/go-playground/validator/v10 v10.20.0 + github.com/go-sql-driver/mysql v1.8.1 + github.com/jmoiron/sqlx v1.4.0 + github.com/mattn/go-sqlite3 v1.14.22 + github.com/rs/zerolog v1.33.0 + gogs.mikescher.com/BlackForestBytes/goext v0.0.463 gopkg.in/loremipsum.v1 v1.1.2 ) require ( - github.com/bytedance/sonic v1.10.2 // indirect - github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect - github.com/chenzhuoyu/iasm v0.9.0 // indirect - github.com/gabriel-vasile/mimetype v1.4.3 // indirect + filippo.io/edwards25519 v1.1.0 // indirect + github.com/bytedance/sonic v1.11.8 // indirect + github.com/bytedance/sonic/loader v0.1.1 // indirect + github.com/cloudwego/base64x v0.1.4 // indirect + github.com/cloudwego/iasm v0.2.0 // indirect + github.com/gabriel-vasile/mimetype v1.4.4 // indirect github.com/gin-contrib/sse v0.1.0 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect - github.com/goccy/go-json v0.10.2 // indirect + github.com/goccy/go-json v0.10.3 // indirect + github.com/golang/snappy v0.0.4 // indirect github.com/google/go-cmp v0.5.9 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/klauspost/cpuid/v2 v2.2.5 // indirect - github.com/leodido/go-urn v1.2.4 // indirect + github.com/klauspost/compress v1.17.8 // indirect + github.com/klauspost/cpuid/v2 v2.2.7 // indirect + github.com/leodido/go-urn v1.4.0 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect - github.com/pelletier/go-toml/v2 v2.1.0 // indirect + github.com/montanaflynn/stats v0.7.1 // indirect + github.com/pelletier/go-toml/v2 v2.2.2 // indirect github.com/rs/xid v1.5.0 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect - github.com/ugorji/go/codec v1.2.11 // indirect - go.mongodb.org/mongo-driver v1.12.1 // indirect - golang.org/x/arch v0.5.0 // indirect - golang.org/x/crypto v0.14.0 // indirect - golang.org/x/net v0.17.0 // indirect - golang.org/x/sys v0.13.0 // indirect - golang.org/x/term v0.13.0 // indirect - golang.org/x/text v0.13.0 // indirect - google.golang.org/protobuf v1.31.0 // indirect + github.com/ugorji/go/codec v1.2.12 // indirect + github.com/xdg-go/pbkdf2 v1.0.0 // indirect + github.com/xdg-go/scram v1.1.2 // indirect + github.com/xdg-go/stringprep v1.0.4 // indirect + github.com/youmark/pkcs8 v0.0.0-20240424034433-3c2c7870ae76 // indirect + go.mongodb.org/mongo-driver v1.15.0 // indirect + golang.org/x/arch v0.8.0 // indirect + golang.org/x/crypto v0.23.0 // indirect + golang.org/x/net v0.25.0 // indirect + golang.org/x/sync v0.7.0 // indirect + golang.org/x/sys v0.20.0 // indirect + golang.org/x/term v0.20.0 // indirect + golang.org/x/text v0.15.0 // indirect + google.golang.org/protobuf v1.34.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/scnserver/go.sum b/scnserver/go.sum index cd2b533..d35a87d 100644 --- a/scnserver/go.sum +++ b/scnserver/go.sum @@ -1,124 +1,135 @@ -github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM= -github.com/bytedance/sonic v1.10.0-rc/go.mod h1:ElCzW+ufi8qKqNW0FY314xriJhyJhuoJ3gFZdAHF7NM= -github.com/bytedance/sonic v1.10.2 h1:GQebETVBxYB7JGWJtLBi07OVzWwt+8dWA00gEVW2ZFE= -github.com/bytedance/sonic v1.10.2/go.mod h1:iZcSUejdk5aukTND/Eu/ivjQuEL0Cu9/rf50Hi0u/g4= -github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY= -github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk= -github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d h1:77cEq6EriyTZ0g/qfRdp61a3Uu/AWrgIq2s0ClJV1g0= -github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d/go.mod h1:8EPpVsBuRksnlj1mLy4AWzRNQYxauNi62uWcE3to6eA= -github.com/chenzhuoyu/iasm v0.9.0 h1:9fhXjVzq5hUy2gkhhgHl95zG2cEAhw9OSGs8toWWAwo= -github.com/chenzhuoyu/iasm v0.9.0/go.mod h1:Xjy2NpN3h7aUqeqM+woSuuvxmIe6+DDsiNLIrkAmYog= +filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= +filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= +github.com/bytedance/sonic v1.11.8 h1:Zw/j1KfiS+OYTi9lyB3bb0CFxPJVkM17k1wyDG32LRA= +github.com/bytedance/sonic v1.11.8/go.mod h1:LysEHSvpvDySVdC2f87zGWf6CIKJcAvqab1ZaiQtds4= +github.com/bytedance/sonic/loader v0.1.1 h1:c+e5Pt1k/cy5wMveRDyk2X4B9hF4g7an8N3zCYjJFNM= +github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= +github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y= +github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= +github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg= +github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= -github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= +github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= +github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= +github.com/gabriel-vasile/mimetype v1.4.4 h1:QjV6pZ7/XZ7ryI2KuyeEDE8wnh7fHP9YnQy+R0LnH8I= +github.com/gabriel-vasile/mimetype v1.4.4/go.mod h1:JwLei5XPtWdGiMFB5Pjle1oEeoSeEuJfJE+TtfvdB/s= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= -github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg= -github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU= +github.com/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU= +github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y= +github.com/glebarez/go-sqlite v1.22.0 h1:uAcMJhaA6r3LHMTFgP0SifzgXg46yJkgxqyuyec+ruQ= +github.com/glebarez/go-sqlite v1.22.0/go.mod h1:PlBIdHe0+aUEFn+r2/uthrWq4FxbzugL0L8Li6yQJbc= github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= +github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= -github.com/go-playground/validator/v10 v10.15.5 h1:LEBecTWb/1j5TNY1YYG2RcOUN3R7NLylN+x8TTueE24= -github.com/go-playground/validator/v10 v10.15.5/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= -github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= -github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI= -github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= -github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= -github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/go-playground/validator/v10 v10.20.0 h1:K9ISHbSaI0lyB2eWMPJo+kOS/FBExVwjEviJTixqxL8= +github.com/go-playground/validator/v10 v10.20.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= +github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y= +github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= +github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA= +github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= +github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/jmoiron/sqlx v1.3.5 h1:vFFPA71p1o5gAeqtEAwLU4dnX2napprKtHr7PYIcN3g= -github.com/jmoiron/sqlx v1.3.5/go.mod h1:nRVWtLre0KfCLJvgxzCsLVMogSvQ1zNJtpYr2Ccp0mQ= +github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU= +github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/jmoiron/sqlx v1.4.0 h1:1PLqN7S1UYp5t4SrVVnt4nUVNemrDAtxlulVe+Qgm3o= +github.com/jmoiron/sqlx v1.4.0/go.mod h1:ZrZ7UsYB/weZdl2Bxg6jCRO9c3YHl8r3ahlKmRT4JLY= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= +github.com/klauspost/compress v1.17.8 h1:YcnTYrq7MikUT7k0Yb5eceMmALQPYBW/Xltxn0NAMnU= +github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= -github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= +github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM= +github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= -github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= -github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= -github.com/lib/pq v1.2.0 h1:LXpIM/LZ5xGFhOpXAQUIMM1HdyqzVYM13zNdjCEEcA0= -github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= +github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= +github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= +github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= -github.com/mattn/go-sqlite3 v1.14.17 h1:mCRHCLDUBXgpKAqIKsaAaAsrAlbkeomtRFKXh2L6YIM= -github.com/mattn/go-sqlite3 v1.14.17/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= +github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU= +github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= -github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4= -github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= +github.com/montanaflynn/stats v0.7.1 h1:etflOAAHORrCC44V+aR6Ftzort912ZU+YLiSTuV8eaE= +github.com/montanaflynn/stats v0.7.1/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow= +github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= +github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= +github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/rs/xid v1.5.0 h1:mKX4bl4iPYJtEIxp6CYiUuLQ/8DYMoz0PUdtGgMFRVc= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= -github.com/rs/zerolog v1.31.0 h1:FcTR3NnLWW+NnTwwhFWiJSZr4ECLpqCm6QsEnyvbV4A= -github.com/rs/zerolog v1.31.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= +github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8= +github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= -github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= -github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= +github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE= +github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= +github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c= github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= +github.com/xdg-go/scram v1.1.2 h1:FHX5I5B4i4hKRVRBCFRxq1iQRej7WO3hhBuJf+UUySY= github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4= +github.com/xdg-go/stringprep v1.0.4 h1:XLI/Ng3O1Atzq0oBs3TWm+5ZVgkq2aqdlvP9JtoZ6c8= github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM= -github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= +github.com/youmark/pkcs8 v0.0.0-20240424034433-3c2c7870ae76 h1:tBiBTKHnIjovYoLX/TPkcf+OjqqKGQrPtGT3Foz+Pgo= +github.com/youmark/pkcs8 v0.0.0-20240424034433-3c2c7870ae76/go.mod h1:SQliXeA7Dhkt//vS29v3zpbEwoa+zb2Cn5xj5uO4K5U= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -go.mongodb.org/mongo-driver v1.12.1 h1:nLkghSU8fQNaK7oUmDhQFsnrtcoNy7Z6LVFKsEecqgE= -go.mongodb.org/mongo-driver v1.12.1/go.mod h1:/rGBTebI3XYboVmgz+Wv3Bcbl3aD0QF9zl6kDDw18rQ= -gogs.mikescher.com/BlackForestBytes/goext v0.0.291 h1:yiRHw8wV9LEZUKljvQ2MBHgeSAI6ZzajDS+FJRGnzVc= -gogs.mikescher.com/BlackForestBytes/goext v0.0.291/go.mod h1:TtMY+/pv09fOldLO3noZ6Yfcy9KU9MjVQ0KQ9nraTeI= +go.mongodb.org/mongo-driver v1.15.0 h1:rJCKC8eEliewXjZGf0ddURtl7tTVy1TK3bfl0gkUSLc= +go.mongodb.org/mongo-driver v1.15.0/go.mod h1:Vzb0Mk/pa7e6cWw85R4F/endUC3u0U9jGcNU603k65c= +gogs.mikescher.com/BlackForestBytes/goext v0.0.463 h1:1sdU/jI7gzzucKv3CBefT1Hk5frGAYvgl/ItC9PdoqA= +gogs.mikescher.com/BlackForestBytes/goext v0.0.463/go.mod h1:ZEaw70t0Wx044Ifkt8fcDHO/KtD3dwgxclX3OF6ElvA= golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= -golang.org/x/arch v0.5.0 h1:jpGode6huXQxcskEIpOCvrU+tzo81b6+oFLUYXWtH/Y= -golang.org/x/arch v0.5.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= +golang.org/x/arch v0.8.0 h1:3wRIsP3pM4yUptoR96otTUOXI367OS0+c9eeRi9doIc= +golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= -golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= +golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= +golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= -golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= +golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -126,28 +137,24 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= -golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= +golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek= -golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= +golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw= +golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= -golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= -golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= +golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= -google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= +google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/loremipsum.v1 v1.1.2 h1:12APklfJKuGszqZsrArW5QoQh03/W+qyCCjvnDuS6Tw= @@ -155,5 +162,13 @@ gopkg.in/loremipsum.v1 v1.1.2/go.mod h1:TuRvzFuzuejXj+odBU6Tubp/EPUyGb9wmSvHenyP gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +modernc.org/libc v1.37.6 h1:orZH3c5wmhIQFTXF+Nt+eeauyd+ZIt2BX6ARe+kD+aw= +modernc.org/libc v1.37.6/go.mod h1:YAXkAZ8ktnkCKaN9sw/UDeUVkGYJ/YquGO4FTi5nmHE= +modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= +modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= +modernc.org/memory v1.7.2 h1:Klh90S215mmH8c9gO98QxQFsY+W451E8AnzjoE2ee1E= +modernc.org/memory v1.7.2/go.mod h1:NO4NVCQy0N7ln+T9ngWqOQfi7ley4vpwvARR+Hjw95E= +modernc.org/sqlite v1.28.0 h1:Zx+LyDDmXczNnEQdvPuEfcFVA2ZPyaD7UCZDjef3BHQ= +modernc.org/sqlite v1.28.0/go.mod h1:Qxpazz0zH8Z1xCFyi5GSL3FzbtZ3fvbjmywNogldEW0= nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= diff --git a/scnserver/models/client.go b/scnserver/models/client.go index 59113b0..0040eaf 100644 --- a/scnserver/models/client.go +++ b/scnserver/models/client.go @@ -12,6 +12,9 @@ type ClientType string //@enum:type const ( ClientTypeAndroid ClientType = "ANDROID" ClientTypeIOS ClientType = "IOS" + ClientTypeLinux ClientType = "LINUX" + ClientTypeMacOS ClientType = "MACOS" + ClientTypeWindows ClientType = "WINDOWS" ) type Client struct { diff --git a/scnserver/models/enums_gen.go b/scnserver/models/enums_gen.go index 0652436..e6ae732 100644 --- a/scnserver/models/enums_gen.go +++ b/scnserver/models/enums_gen.go @@ -5,23 +5,30 @@ package models import "gogs.mikescher.com/BlackForestBytes/goext/langext" import "gogs.mikescher.com/BlackForestBytes/goext/enums" -const ChecksumEnumGenerator = "8926e4a9845e67086109bef7ca447371ab5c0a94fcfd988f14fd4ee98da9e932" // GoExtVersion: 0.0.291 +const ChecksumEnumGenerator = "69a99f8c01a15baad2fc9b99c516a700e02ce4dbcae452699e6d43cc23bc01bc" // GoExtVersion: 0.0.463 // ================================ ClientType ================================ // // File: client.go // StringEnum: true // DescrEnum: false +// DataEnum: false // var __ClientTypeValues = []ClientType{ ClientTypeAndroid, ClientTypeIOS, + ClientTypeLinux, + ClientTypeMacOS, + ClientTypeWindows, } var __ClientTypeVarnames = map[ClientType]string{ ClientTypeAndroid: "ClientTypeAndroid", ClientTypeIOS: "ClientTypeIOS", + ClientTypeLinux: "ClientTypeLinux", + ClientTypeMacOS: "ClientTypeMacOS", + ClientTypeWindows: "ClientTypeWindows", } func (e ClientType) Valid() bool { @@ -51,6 +58,14 @@ func (e ClientType) VarName() string { return "" } +func (e ClientType) TypeName() string { + return "ClientType" +} + +func (e ClientType) PackageName() string { + return "models" +} + func (e ClientType) Meta() enums.EnumMetaValue { return enums.EnumMetaValue{VarName: e.VarName(), Value: e, Description: nil} } @@ -72,6 +87,9 @@ func ClientTypeValuesMeta() []enums.EnumMetaValue { return []enums.EnumMetaValue{ ClientTypeAndroid.Meta(), ClientTypeIOS.Meta(), + ClientTypeLinux.Meta(), + ClientTypeMacOS.Meta(), + ClientTypeWindows.Meta(), } } @@ -80,6 +98,7 @@ func ClientTypeValuesMeta() []enums.EnumMetaValue { // File: delivery.go // StringEnum: true // DescrEnum: false +// DataEnum: false // var __DeliveryStatusValues = []DeliveryStatus{ @@ -121,6 +140,14 @@ func (e DeliveryStatus) VarName() string { return "" } +func (e DeliveryStatus) TypeName() string { + return "DeliveryStatus" +} + +func (e DeliveryStatus) PackageName() string { + return "models" +} + func (e DeliveryStatus) Meta() enums.EnumMetaValue { return enums.EnumMetaValue{VarName: e.VarName(), Value: e, Description: nil} } @@ -151,6 +178,7 @@ func DeliveryStatusValuesMeta() []enums.EnumMetaValue { // File: keytoken.go // StringEnum: true // DescrEnum: true +// DataEnum: false // var __TokenPermValues = []TokenPerm{ @@ -208,10 +236,22 @@ func (e TokenPerm) VarName() string { return "" } +func (e TokenPerm) TypeName() string { + return "TokenPerm" +} + +func (e TokenPerm) PackageName() string { + return "models" +} + func (e TokenPerm) Meta() enums.EnumMetaValue { return enums.EnumMetaValue{VarName: e.VarName(), Value: e, Description: langext.Ptr(e.Description())} } +func (e TokenPerm) DescriptionMeta() enums.EnumDescriptionMetaValue { + return enums.EnumDescriptionMetaValue{VarName: e.VarName(), Value: e, Description: e.Description()} +} + func ParseTokenPerm(vv string) (TokenPerm, bool) { for _, ev := range __TokenPermValues { if string(ev) == vv { @@ -233,3 +273,22 @@ func TokenPermValuesMeta() []enums.EnumMetaValue { PermUserRead.Meta(), } } + +func TokenPermValuesDescriptionMeta() []enums.EnumDescriptionMetaValue { + return []enums.EnumDescriptionMetaValue{ + PermAdmin.DescriptionMeta(), + PermChannelRead.DescriptionMeta(), + PermChannelSend.DescriptionMeta(), + PermUserRead.DescriptionMeta(), + } +} + +// ================================ ================= ================================ + +func AllPackageEnums() []enums.Enum { + return []enums.Enum{ + ClientTypeAndroid, // ClientType + DeliveryStatusRetry, // DeliveryStatus + PermAdmin, // TokenPerm + } +} diff --git a/scnserver/models/ids_gen.go b/scnserver/models/ids_gen.go index ae673cd..8fd4682 100644 --- a/scnserver/models/ids_gen.go +++ b/scnserver/models/ids_gen.go @@ -1,8 +1,9 @@ -// Code generated by id-generate.go DO NOT EDIT. +// Code generated by csid-generate.go DO NOT EDIT. package models import "crypto/rand" +import "crypto/sha256" import "fmt" import "github.com/go-playground/validator/v10" import "github.com/rs/zerolog/log" @@ -14,7 +15,7 @@ import "reflect" import "regexp" import "strings" -const ChecksumCharsetIDGenerator = "8926e4a9845e67086109bef7ca447371ab5c0a94fcfd988f14fd4ee98da9e932" // GoExtVersion: 0.0.291 +const ChecksumCharsetIDGenerator = "69a99f8c01a15baad2fc9b99c516a700e02ce4dbcae452699e6d43cc23bc01bc" // GoExtVersion: 0.0.463 const idlen = 24 @@ -64,10 +65,10 @@ func generateCharsetMap() []int { func generateID(prefix string) string { k := "" - max := big.NewInt(int64(idCharsetLen)) + csMax := big.NewInt(int64(idCharsetLen)) checksum := 0 for i := 0; i < idlen-len(prefix)-checklen; i++ { - v, err := rand.Int(rand.Reader, max) + v, err := rand.Int(rand.Reader, csMax) if err != nil { panic(err) } @@ -79,6 +80,27 @@ func generateID(prefix string) string { return prefix + k + checkstr } +func generateIDFromSeed(prefix string, seed string) string { + h := sha256.New() + + iddata := "" + for len(iddata) < idlen-len(prefix)-checklen { + h.Write([]byte(seed)) + bs := h.Sum(nil) + iddata += langext.NewAnyBaseConverter(idCharset).Encode(bs) + } + + checksum := 0 + for i := 0; i < idlen-len(prefix)-checklen; i++ { + ichr := int(iddata[i]) + checksum = (checksum + charSetReverseMap[ichr]) % (idCharsetLen) + } + + checkstr := string(idCharset[checksum%idCharsetLen]) + + return prefix + iddata[:(idlen-len(prefix)-checklen)] + checkstr +} + func validateID(prefix string, value string) error { if len(value) != idlen { return exerr.New(exerr.TypeInvalidCSID, "id has the wrong length").Str("value", value).Build() diff --git a/scnserver/swagger/swagger.json b/scnserver/swagger/swagger.json index dd5fb8b..44bdce8 100644 --- a/scnserver/swagger/swagger.json +++ b/scnserver/swagger/swagger.json @@ -3037,7 +3037,7 @@ "type": "string" }, "client_type": { - "type": "string" + "$ref": "#/definitions/models.ClientType" }, "fcm_token": { "type": "string" @@ -3082,7 +3082,7 @@ "type": "string" }, "client_type": { - "type": "string" + "$ref": "#/definitions/models.ClientType" }, "fcm_token": { "type": "string" @@ -3653,11 +3653,17 @@ "type": "string", "enum": [ "ANDROID", - "IOS" + "IOS", + "LINUX", + "MACOS", + "WINDOWS" ], "x-enum-varnames": [ "ClientTypeAndroid", - "ClientTypeIOS" + "ClientTypeIOS", + "ClientTypeLinux", + "ClientTypeMacOS", + "ClientTypeWindows" ] }, "models.CompatMessage": { diff --git a/scnserver/swagger/swagger.yaml b/scnserver/swagger/swagger.yaml index 4325685..a4f0f08 100644 --- a/scnserver/swagger/swagger.yaml +++ b/scnserver/swagger/swagger.yaml @@ -128,7 +128,7 @@ definitions: agent_version: type: string client_type: - type: string + $ref: '#/definitions/models.ClientType' fcm_token: type: string required: @@ -162,7 +162,7 @@ definitions: agent_version: type: string client_type: - type: string + $ref: '#/definitions/models.ClientType' fcm_token: type: string no_client: @@ -538,10 +538,16 @@ definitions: enum: - ANDROID - IOS + - LINUX + - MACOS + - WINDOWS type: string x-enum-varnames: - ClientTypeAndroid - ClientTypeIOS + - ClientTypeLinux + - ClientTypeMacOS + - ClientTypeWindows models.CompatMessage: properties: body: diff --git a/scnserver/website/scn_send.html b/scnserver/website/scn_send.html index cf58d65..e69de29 100644 --- a/scnserver/website/scn_send.html +++ b/scnserver/website/scn_send.html @@ -1,185 +0,0 @@ -
#!/usr/bin/env bash
-
-#
-# Wrapper around SCN ( https://simplecloudnotifier.de/ )
-# ======================================================
-#
-# ./scn_send [@channel] title [content] [priority]
-#
-#
-# Call with   scn_send              "${title}"
-#        or   scn_send              "${title}" ${content}"
-#        or   scn_send              "${title}" ${content}" "${priority:0|1|2}"
-#        or   scn_send "@${channel} "${title}"
-#        or   scn_send "@${channel} "${title}" ${content}"
-#        or   scn_send "@${channel} "${title}" ${content}" "${priority:0|1|2}"
-#
-# content can be of format "--scnsend-read-body-from-file={path}" to read body from file
-# (this circumvents max commandline length)
-#
-
-################################################################################
-
-usage() {
-    echo "Usage: "
-    echo "  scn_send [@channel] title [content] [priority]"
-    echo ""
-}
-
-function cfgcol { [ -t 1 ] && [ -n "$(tput colors)" ] && [ "$(tput colors)" -ge 8 ]; }
-
-function rederr() { if cfgcol; then >&2 echo -e "\x1B[31m$1\x1B[0m"; else >&2 echo "$1"; fi; }
-function green()  { if cfgcol; then     echo -e "\x1B[32m$1\x1B[0m"; else     echo "$1"; fi; }
-
-################################################################################
-
-#
-# Get env 'SCN_UID' and 'SCN_KEY' from conf file
-# 
-# shellcheck source=/dev/null
-. "/etc/scn.conf"
-SCN_UID=${SCN_UID:-}
-SCN_KEY=${SCN_KEY:-}
-
-[ -z "${SCN_UID}" ] && { rederr "Missing config value 'SCN_UID' in /etc/scn.conf"; exit 1; }
-[ -z "${SCN_KEY}" ] && { rederr "Missing config value 'SCN_KEY' in /etc/scn.conf"; exit 1; }
-
-################################################################################
-
-args=( "$@" )
-
-title=""
-content=""
-channel=""
-priority=""
-usr_msg_id="$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 32)"
-sendtime="$(date +%s)"
-sender="$(hostname)"
-
-if command -v srvname &> /dev/null; then
-  sender="$( srvname )"
-fi
-
-if [[ "${args[0]}" = "--" ]]; then
-    # only positional args form here on (currently not handled)
-    args=("${args[@]:1}")
-fi
-
-if [ ${#args[@]} -lt 1 ]; then
-    rederr "[ERROR]: no title supplied via parameter"
-    usage
-    exit 1
-fi
-
-if [[ "${args[0]}" =~ ^@.* ]]; then
-    channel="${args[0]}"
-    args=("${args[@]:1}")
-    channel="${channel:1}"
-fi
-
-if [ ${#args[@]} -lt 1 ]; then
-    rederr "[ERROR]: no title supplied via parameter"
-    usage
-    exit 1
-fi
-
-title="${args[0]}"
-args=("${args[@]:1}")
-
-content=""
-
-if [ ${#args[@]} -gt 0 ]; then
-    content="${args[0]}"
-    args=("${args[@]:1}")
-fi
-
-if [ ${#args[@]} -gt 0 ]; then
-    priority="${args[0]}"
-    args=("${args[@]:1}")
-fi
-
-if [ ${#args[@]} -gt 0 ]; then
-    rederr "Too many arguments to scn_send"
-    usage
-    exit 1
-fi
-
-if [[ "$content" == --scnsend-read-body-from-file=* ]]; then
-  path="$( awk '{ print substr($0, 31) }' <<< "$content" )"
-  content="$( cat "$path" )"
-fi
-
-curlparams=()
-
-curlparams+=( "--data-urlencode" "user_id=${SCN_UID}"  )
-curlparams+=( "--data-urlencode" "key=${SCN_KEY}"      )
-curlparams+=( "--data-urlencode" "title=$title"        )
-curlparams+=( "--data-urlencode" "timestamp=$sendtime" )
-curlparams+=( "--data-urlencode" "msg_id=$usr_msg_id"  )
-
-if [[ -n "$content" ]]; then
-    curlparams+=("--data-urlencode" "content=$content")
-fi
-
-if [[ -n "$priority" ]]; then
-    curlparams+=("--data-urlencode" "priority=$priority")
-fi
-
-if [[ -n "$channel" ]]; then
-    curlparams+=("--data-urlencode" "channel=$channel")
-fi
-
-if [[ -n "$sender" ]]; then
-    curlparams+=("--data-urlencode" "sender_name=$sender")
-fi
-
-while true ; do
-
-    outf="$(mktemp)"
-
-    curlresp=$(curl --silent                             \
-                    --output "${outf}"                   \
-                    --write-out "%{http_code}"           \
-                    "${curlparams[@]}"                   \
-                    "https://simplecloudnotifier.de/"    )
-
-    curlout="$(cat "$outf")"
-    rm "$outf"
-
-    if [ "$curlresp" == 200 ] ; then
-        green "Successfully send"
-        exit 0
-    fi
-
-    if [ "$curlresp" == 400 ] ; then
-        rederr "Bad request - something went wrong"
-        echo "$curlout"
-        echo ""
-        exit 1
-    fi
-
-    if [ "$curlresp" == 401 ] ; then
-        rederr "Unauthorized - wrong userid/userkey"
-        exit 1
-    fi
-
-    if [ "$curlresp" == 403 ] ; then
-        rederr "Quota exceeded - wait 5 min before re-try"
-        sleep 300
-    fi
-
-    if [ "$curlresp" == 412 ] ; then
-        rederr "Precondition Failed - No device linked"
-        exit 1
-    fi
-
-    if [ "$curlresp" == 500 ] ; then
-        rederr "Internal server error - waiting for better times"
-        sleep 60
-    fi
-
-    # if none of the above matched we probably have no network ...
-    rederr "Send failed (response code $curlresp) ... try again in 5s"
-    sleep 5
-done
-