Browse Source

WIP: BROKEN FOR ELECTRON: Fixes in progress

pull/137/head
Matthew Raymer 1 week ago
parent
commit
229d9184b2
  1. 101
      -1748433586226.log
  2. 446
      package-lock.json
  3. 270
      scripts/build-electron.js
  4. 5
      src/db-sql/migration.ts
  5. 86
      src/db/databaseUtil.ts
  6. 31
      src/electron/preload.js
  7. 37
      src/interfaces/common.ts
  8. 18
      src/libs/crypto/vc/passkeyDidPeer.ts
  9. 188
      src/libs/endorserServer.ts
  10. 27
      src/libs/util.ts
  11. 6
      src/main.common.ts
  12. 12
      src/main.electron.ts
  13. 18
      src/main.web.ts
  14. 4
      src/services/AbsurdSqlDatabaseService.ts
  15. 13
      src/services/QRScanner/CapacitorQRScanner.ts
  16. 5
      src/services/QRScanner/WebInlineQRScanner.ts
  17. 6
      src/services/deepLinks.ts
  18. 6
      src/utils/logger.ts
  19. 4
      src/views/ContactsView.vue
  20. 3
      src/views/ImportAccountView.vue

101
-1748433586226.log

@ -0,0 +1,101 @@
VM5:29 [Preload] Preload script starting...
VM5:29 [Preload] Preload script completed successfully
main.common-DiOUyXe7.js:27 Platform Object
error @ main.common-DiOUyXe7.js:27
main.common-DiOUyXe7.js:27 PWA enabled Object
error @ main.common-DiOUyXe7.js:27
main.common-DiOUyXe7.js:27 [Web] PWA enabled Object
error @ main.common-DiOUyXe7.js:27
main.common-DiOUyXe7.js:27 [Web] Platform Object
error @ main.common-DiOUyXe7.js:27
main.common-DiOUyXe7.js:29 Opened!
main.common-DiOUyXe7.js:2552 Failed to log to database: Error: no such column: value
at E.handleError (main.common-DiOUyXe7.js:27:21133)
at E.exec (main.common-DiOUyXe7.js:27:19785)
at Rc.processQueue (main.common-DiOUyXe7.js:2379:2368)
F7 @ main.common-DiOUyXe7.js:2552
main.common-DiOUyXe7.js:2552 Original message: PWA enabled - [{"pwa_enabled":false}]
F7 @ main.common-DiOUyXe7.js:2552
main.common-DiOUyXe7.js:2552 Failed to log to database: Error: no such column: value
at E.handleError (main.common-DiOUyXe7.js:27:21133)
at E.exec (main.common-DiOUyXe7.js:27:19785)
at Rc.processQueue (main.common-DiOUyXe7.js:2379:2368)
at main.common-DiOUyXe7.js:2379:2816
at new Promise (<anonymous>)
at Rc.queueOperation (main.common-DiOUyXe7.js:2379:2685)
at Rc.query (main.common-DiOUyXe7.js:2379:3378)
at async F7 (main.common-DiOUyXe7.js:2552:117)
F7 @ main.common-DiOUyXe7.js:2552
main.common-DiOUyXe7.js:2552 Original message: [Web] PWA enabled - [{"pwa_enabled":false}]
F7 @ main.common-DiOUyXe7.js:2552
main.common-DiOUyXe7.js:2552 Failed to log to database: Error: no such column: value
at E.handleError (main.common-DiOUyXe7.js:27:21133)
at E.exec (main.common-DiOUyXe7.js:27:19785)
at Rc.processQueue (main.common-DiOUyXe7.js:2379:2368)
at main.common-DiOUyXe7.js:2379:2816
at new Promise (<anonymous>)
at Rc.queueOperation (main.common-DiOUyXe7.js:2379:2685)
at Rc.query (main.common-DiOUyXe7.js:2379:3378)
at async F7 (main.common-DiOUyXe7.js:2552:117)
F7 @ main.common-DiOUyXe7.js:2552
main.common-DiOUyXe7.js:2552 Original message: [Web] Platform - [{"platform":"web"}]
F7 @ main.common-DiOUyXe7.js:2552
main.common-DiOUyXe7.js:2552 Failed to log to database: Error: no such column: value
at E.handleError (main.common-DiOUyXe7.js:27:21133)
at E.exec (main.common-DiOUyXe7.js:27:19785)
at Rc.processQueue (main.common-DiOUyXe7.js:2379:2368)
at main.common-DiOUyXe7.js:2379:2816
at new Promise (<anonymous>)
at Rc.queueOperation (main.common-DiOUyXe7.js:2379:2685)
at Rc.query (main.common-DiOUyXe7.js:2379:3378)
at async F7 (main.common-DiOUyXe7.js:2552:117)
F7 @ main.common-DiOUyXe7.js:2552
main.common-DiOUyXe7.js:2552 Original message: Platform - [{"platform":"web"}]
F7 @ main.common-DiOUyXe7.js:2552
main.common-DiOUyXe7.js:2100
GET https://api.endorser.ch/api/report/rateLimits 400 (Bad Request)
(anonymous) @ main.common-DiOUyXe7.js:2100
xhr @ main.common-DiOUyXe7.js:2100
p6 @ main.common-DiOUyXe7.js:2102
_request @ main.common-DiOUyXe7.js:2103
request @ main.common-DiOUyXe7.js:2102
Yc.<computed> @ main.common-DiOUyXe7.js:2103
(anonymous) @ main.common-DiOUyXe7.js:2098
dJ @ main.common-DiOUyXe7.js:2295
main.common-DiOUyXe7.js:2100
GET https://api.endorser.ch/api/report/rateLimits 400 (Bad Request)
(anonymous) @ main.common-DiOUyXe7.js:2100
xhr @ main.common-DiOUyXe7.js:2100
p6 @ main.common-DiOUyXe7.js:2102
_request @ main.common-DiOUyXe7.js:2103
request @ main.common-DiOUyXe7.js:2102
Yc.<computed> @ main.common-DiOUyXe7.js:2103
(anonymous) @ main.common-DiOUyXe7.js:2098
dJ @ main.common-DiOUyXe7.js:2295
await in dJ
checkRegistrationStatus @ HomeView-DJMSCuMg.js:1
mounted @ HomeView-DJMSCuMg.js:1
XMLHttpRequest.send
(anonymous) @ main.common-DiOUyXe7.js:2100
xhr @ main.common-DiOUyXe7.js:2100
p6 @ main.common-DiOUyXe7.js:2102
_request @ main.common-DiOUyXe7.js:2103
request @ main.common-DiOUyXe7.js:2102
Yc.<computed> @ main.common-DiOUyXe7.js:2103
(anonymous) @ main.common-DiOUyXe7.js:2098
ZG @ main.common-DiOUyXe7.js:2295
await in ZG
initializeIdentity @ HomeView-DJMSCuMg.js:1
XMLHttpRequest.send
(anonymous) @ main.common-DiOUyXe7.js:2100
xhr @ main.common-DiOUyXe7.js:2100
p6 @ main.common-DiOUyXe7.js:2102
_request @ main.common-DiOUyXe7.js:2103
request @ main.common-DiOUyXe7.js:2102
Yc.<computed> @ main.common-DiOUyXe7.js:2103
(anonymous) @ main.common-DiOUyXe7.js:2098
dJ @ main.common-DiOUyXe7.js:2295

446
package-lock.json

@ -205,9 +205,9 @@
} }
}, },
"node_modules/@babel/compat-data": { "node_modules/@babel/compat-data": {
"version": "7.27.2", "version": "7.27.3",
"resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.27.2.tgz", "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.27.3.tgz",
"integrity": "sha512-TUtMJYRPyUb/9aU8f3K0mjmjf6M9N5Woshn2CS6nqJSeJtTtQcpLUXjGt9vbF8ZGff0El99sWkLgzwW3VXnxZQ==", "integrity": "sha512-V42wFfx1ymFte+ecf6iXghnnP8kWTO+ZLXIyZq+1LAXHHvTZdVxicn4yiVYdYMGaCO3tmqub11AorKkv+iodqw==",
"devOptional": true, "devOptional": true,
"license": "MIT", "license": "MIT",
"engines": { "engines": {
@ -215,22 +215,22 @@
} }
}, },
"node_modules/@babel/core": { "node_modules/@babel/core": {
"version": "7.27.1", "version": "7.27.3",
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.27.1.tgz", "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.27.3.tgz",
"integrity": "sha512-IaaGWsQqfsQWVLqMn9OB92MNN7zukfVA4s7KKAI0KfrrDsZ0yhi5uV4baBuLuN7n3vsZpwP8asPPcVwApxvjBQ==", "integrity": "sha512-hyrN8ivxfvJ4i0fIJuV4EOlV0WDMz5Ui4StRTgVaAvWeiRCilXgwVvxJKtFQ3TKtHgJscB2YiXKGNJuVwhQMtA==",
"devOptional": true, "devOptional": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@ampproject/remapping": "^2.2.0", "@ampproject/remapping": "^2.2.0",
"@babel/code-frame": "^7.27.1", "@babel/code-frame": "^7.27.1",
"@babel/generator": "^7.27.1", "@babel/generator": "^7.27.3",
"@babel/helper-compilation-targets": "^7.27.1", "@babel/helper-compilation-targets": "^7.27.2",
"@babel/helper-module-transforms": "^7.27.1", "@babel/helper-module-transforms": "^7.27.3",
"@babel/helpers": "^7.27.1", "@babel/helpers": "^7.27.3",
"@babel/parser": "^7.27.1", "@babel/parser": "^7.27.3",
"@babel/template": "^7.27.1", "@babel/template": "^7.27.2",
"@babel/traverse": "^7.27.1", "@babel/traverse": "^7.27.3",
"@babel/types": "^7.27.1", "@babel/types": "^7.27.3",
"convert-source-map": "^2.0.0", "convert-source-map": "^2.0.0",
"debug": "^4.1.0", "debug": "^4.1.0",
"gensync": "^1.0.0-beta.2", "gensync": "^1.0.0-beta.2",
@ -256,14 +256,14 @@
} }
}, },
"node_modules/@babel/generator": { "node_modules/@babel/generator": {
"version": "7.27.1", "version": "7.27.3",
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.27.1.tgz", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.27.3.tgz",
"integrity": "sha512-UnJfnIpc/+JO0/+KRVQNGU+y5taA5vCbwN8+azkX6beii/ZF+enZJSOKo11ZSzGJjlNfJHfQtmQT8H+9TXPG2w==", "integrity": "sha512-xnlJYj5zepml8NXtjkG0WquFUv8RskFqyFcVgTBp5k+NaA/8uw/K+OSVf8AMGw5e9HKP2ETd5xpK5MLZQD6b4Q==",
"devOptional": true, "devOptional": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@babel/parser": "^7.27.1", "@babel/parser": "^7.27.3",
"@babel/types": "^7.27.1", "@babel/types": "^7.27.3",
"@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/gen-mapping": "^0.3.5",
"@jridgewell/trace-mapping": "^0.3.25", "@jridgewell/trace-mapping": "^0.3.25",
"jsesc": "^3.0.2" "jsesc": "^3.0.2"
@ -273,13 +273,13 @@
} }
}, },
"node_modules/@babel/helper-annotate-as-pure": { "node_modules/@babel/helper-annotate-as-pure": {
"version": "7.27.1", "version": "7.27.3",
"resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.1.tgz", "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz",
"integrity": "sha512-WnuuDILl9oOBbKnb4L+DyODx7iC47XfzmNCpTttFsSp6hTG7XZxu60+4IO+2/hPfcGOoKbFiwoI/+zwARbNQow==", "integrity": "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==",
"devOptional": true, "devOptional": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@babel/types": "^7.27.1" "@babel/types": "^7.27.3"
}, },
"engines": { "engines": {
"node": ">=6.9.0" "node": ">=6.9.0"
@ -435,15 +435,15 @@
} }
}, },
"node_modules/@babel/helper-module-transforms": { "node_modules/@babel/helper-module-transforms": {
"version": "7.27.1", "version": "7.27.3",
"resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.27.1.tgz", "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.27.3.tgz",
"integrity": "sha512-9yHn519/8KvTU5BjTVEEeIM3w9/2yXNKoD82JifINImhpKkARMJKPP59kLo+BafpdN5zgNeIcS4jsGDmd3l58g==", "integrity": "sha512-dSOvYwvyLsWBeIRyOeHXp5vPj5l1I011r52FM1+r1jCERv+aFXYk4whgQccYEGYxK2H3ZAIA8nuPkQ0HaUo3qg==",
"devOptional": true, "devOptional": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@babel/helper-module-imports": "^7.27.1", "@babel/helper-module-imports": "^7.27.1",
"@babel/helper-validator-identifier": "^7.27.1", "@babel/helper-validator-identifier": "^7.27.1",
"@babel/traverse": "^7.27.1" "@babel/traverse": "^7.27.3"
}, },
"engines": { "engines": {
"node": ">=6.9.0" "node": ">=6.9.0"
@ -569,14 +569,14 @@
} }
}, },
"node_modules/@babel/helpers": { "node_modules/@babel/helpers": {
"version": "7.27.1", "version": "7.27.3",
"resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.27.1.tgz", "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.27.3.tgz",
"integrity": "sha512-FCvFTm0sWV8Fxhpp2McP5/W53GPllQ9QeQ7SiqGWjMf/LVG07lFa5+pgK05IRhVwtvafT22KF+ZSnM9I545CvQ==", "integrity": "sha512-h/eKy9agOya1IGuLaZ9tEUgz+uIRXcbtOhRtUyyMf8JFmn1iT13vnl/IGVWSkdOCG/pC57U4S1jnAabAavTMwg==",
"devOptional": true, "devOptional": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@babel/template": "^7.27.1", "@babel/template": "^7.27.2",
"@babel/types": "^7.27.1" "@babel/types": "^7.27.3"
}, },
"engines": { "engines": {
"node": ">=6.9.0" "node": ">=6.9.0"
@ -685,12 +685,12 @@
} }
}, },
"node_modules/@babel/parser": { "node_modules/@babel/parser": {
"version": "7.27.2", "version": "7.27.3",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.27.2.tgz", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.27.3.tgz",
"integrity": "sha512-QYLs8299NA7WM/bZAdp+CviYYkVoYXlDW2rzliy3chxd1PQjej7JORuMJDJXJUb9g0TT+B99EwaVLKmX+sPXWw==", "integrity": "sha512-xyYxRj6+tLNDTWi0KCBcZ9V7yg3/lwL9DWh9Uwh/RIVlIfFidggcgxKX3GCXwCiswwcGRawBKbEg2LG/Y8eJhw==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@babel/types": "^7.27.1" "@babel/types": "^7.27.3"
}, },
"bin": { "bin": {
"parser": "bin/babel-parser.js" "parser": "bin/babel-parser.js"
@ -1285,9 +1285,9 @@
} }
}, },
"node_modules/@babel/plugin-transform-block-scoping": { "node_modules/@babel/plugin-transform-block-scoping": {
"version": "7.27.1", "version": "7.27.3",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.27.1.tgz", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.27.3.tgz",
"integrity": "sha512-QEcFlMl9nGTgh1rn2nIeU5bkfb9BAjaQcWbiP4LvKxUot52ABcTkpcyJ7f2Q2U2RuQ84BNLgts3jRme2dTx6Fw==", "integrity": "sha512-+F8CnfhuLhwUACIJMLWnjz6zvzYM2r0yeIHKlbgfw7ml8rOMJsXNXV/hyRcb3nb493gRs4WvYpQAndWj/qQmkQ==",
"devOptional": true, "devOptional": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
@ -1383,9 +1383,9 @@
} }
}, },
"node_modules/@babel/plugin-transform-destructuring": { "node_modules/@babel/plugin-transform-destructuring": {
"version": "7.27.1", "version": "7.27.3",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.27.1.tgz", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.27.3.tgz",
"integrity": "sha512-ttDCqhfvpE9emVkXbPD8vyxxh4TWYACVybGkDj+oReOGwnp066ITEivDlLwe0b1R0+evJ13IXQuLNB5w1fhC5Q==", "integrity": "sha512-s4Jrok82JpiaIprtY2nHsYmrThKvvwgHwjgd7UMiYhZaN0asdXNLr0y+NjTfkA7SyQE5i2Fb7eawUOZmLvyqOA==",
"devOptional": true, "devOptional": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
@ -1749,15 +1749,15 @@
} }
}, },
"node_modules/@babel/plugin-transform-object-rest-spread": { "node_modules/@babel/plugin-transform-object-rest-spread": {
"version": "7.27.2", "version": "7.27.3",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.27.2.tgz", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.27.3.tgz",
"integrity": "sha512-AIUHD7xJ1mCrj3uPozvtngY3s0xpv7Nu7DoUSnzNY6Xam1Cy4rUznR//pvMHOhQ4AvbCexhbqXCtpxGHOGOO6g==", "integrity": "sha512-7ZZtznF9g4l2JCImCo5LNKFHB5eXnN39lLtLY5Tg+VkR0jwOt7TBciMckuiQIOIW7L5tkQOCh3bVGYeXgMx52Q==",
"devOptional": true, "devOptional": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-compilation-targets": "^7.27.2",
"@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-plugin-utils": "^7.27.1",
"@babel/plugin-transform-destructuring": "^7.27.1", "@babel/plugin-transform-destructuring": "^7.27.3",
"@babel/plugin-transform-parameters": "^7.27.1" "@babel/plugin-transform-parameters": "^7.27.1"
}, },
"engines": { "engines": {
@ -2041,9 +2041,9 @@
} }
}, },
"node_modules/@babel/plugin-transform-runtime": { "node_modules/@babel/plugin-transform-runtime": {
"version": "7.27.1", "version": "7.27.3",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.27.1.tgz", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.27.3.tgz",
"integrity": "sha512-TqGF3desVsTcp3WrJGj4HfKokfCXCLcHpt4PJF0D8/iT6LPd9RS82Upw3KPeyr6B22Lfd3DO8MVrmp0oRkUDdw==", "integrity": "sha512-bA9ZL5PW90YwNgGfjg6U+7Qh/k3zCEQJ06BFgAGRp/yMjw9hP9UGbGPtx3KSOkHGljEPCCxaE+PH4fUR2h1sDw==",
"license": "MIT", "license": "MIT",
"optional": true, "optional": true,
"peer": true, "peer": true,
@ -2395,9 +2395,9 @@
} }
}, },
"node_modules/@babel/runtime": { "node_modules/@babel/runtime": {
"version": "7.27.1", "version": "7.27.3",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.1.tgz", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.3.tgz",
"integrity": "sha512-1x3D2xEk2fRo3PAhwQwu5UubzgiVWSXTBfWpVd2Mx2AzRqJuDJCsgaDVZ7HB5iGzDW1Hl1sWN2mFyKjmR9uAog==", "integrity": "sha512-7EYtGezsdiDMyY80+65EzwiGmcJqpmcZCojSXaRgdrBaGtWTgDZKq69cPIVped6MkIM78cTQ2GOiEYjwOlG4xw==",
"devOptional": true, "devOptional": true,
"license": "MIT", "license": "MIT",
"engines": { "engines": {
@ -2420,17 +2420,17 @@
} }
}, },
"node_modules/@babel/traverse": { "node_modules/@babel/traverse": {
"version": "7.27.1", "version": "7.27.3",
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.27.1.tgz", "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.27.3.tgz",
"integrity": "sha512-ZCYtZciz1IWJB4U61UPu4KEaqyfj+r5T1Q5mqPo+IBpcG9kHv30Z0aD8LXPgC1trYa6rK0orRyAhqUgk4MjmEg==", "integrity": "sha512-lId/IfN/Ye1CIu8xG7oKBHXd2iNb2aW1ilPszzGcJug6M8RCKfVNcYhpI5+bMvFYjK7lXIM0R+a+6r8xhHp2FQ==",
"devOptional": true, "devOptional": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@babel/code-frame": "^7.27.1", "@babel/code-frame": "^7.27.1",
"@babel/generator": "^7.27.1", "@babel/generator": "^7.27.3",
"@babel/parser": "^7.27.1", "@babel/parser": "^7.27.3",
"@babel/template": "^7.27.1", "@babel/template": "^7.27.2",
"@babel/types": "^7.27.1", "@babel/types": "^7.27.3",
"debug": "^4.3.1", "debug": "^4.3.1",
"globals": "^11.1.0" "globals": "^11.1.0"
}, },
@ -2440,18 +2440,18 @@
}, },
"node_modules/@babel/traverse--for-generate-function-map": { "node_modules/@babel/traverse--for-generate-function-map": {
"name": "@babel/traverse", "name": "@babel/traverse",
"version": "7.27.1", "version": "7.27.3",
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.27.1.tgz", "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.27.3.tgz",
"integrity": "sha512-ZCYtZciz1IWJB4U61UPu4KEaqyfj+r5T1Q5mqPo+IBpcG9kHv30Z0aD8LXPgC1trYa6rK0orRyAhqUgk4MjmEg==", "integrity": "sha512-lId/IfN/Ye1CIu8xG7oKBHXd2iNb2aW1ilPszzGcJug6M8RCKfVNcYhpI5+bMvFYjK7lXIM0R+a+6r8xhHp2FQ==",
"license": "MIT", "license": "MIT",
"optional": true, "optional": true,
"peer": true, "peer": true,
"dependencies": { "dependencies": {
"@babel/code-frame": "^7.27.1", "@babel/code-frame": "^7.27.1",
"@babel/generator": "^7.27.1", "@babel/generator": "^7.27.3",
"@babel/parser": "^7.27.1", "@babel/parser": "^7.27.3",
"@babel/template": "^7.27.1", "@babel/template": "^7.27.2",
"@babel/types": "^7.27.1", "@babel/types": "^7.27.3",
"debug": "^4.3.1", "debug": "^4.3.1",
"globals": "^11.1.0" "globals": "^11.1.0"
}, },
@ -2481,9 +2481,9 @@
} }
}, },
"node_modules/@babel/types": { "node_modules/@babel/types": {
"version": "7.27.1", "version": "7.27.3",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.27.1.tgz", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.27.3.tgz",
"integrity": "sha512-+EzkxvLNfiUeKMgy/3luqfsCWFRXLb7U6wNQTk60tovuckwB15B191tJWvpp4HjiQWdJkCxO3Wbvc6jlk3Xb2Q==", "integrity": "sha512-Y1GkI4ktrtvmawoSq+4FCVHNryea6uR+qUQy0AGxLSsjCX0nVmkYQMBLHDkXZuo5hGx7eYdnIaslsdBFm7zbUw==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@babel/helper-string-parser": "^7.27.1", "@babel/helper-string-parser": "^7.27.1",
@ -8189,13 +8189,12 @@
] ]
}, },
"node_modules/@rollup/rollup-darwin-arm64": { "node_modules/@rollup/rollup-darwin-arm64": {
"version": "4.41.1", "version": "4.34.9",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.41.1.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.34.9.tgz",
"integrity": "sha512-5afxvwszzdulsU2w8JKWwY8/sJOLPzf0e1bFuvcW5h9zsEg+RQAojdW0ux2zyYAz7R8HvvzKCjLNJhVq965U7w==", "integrity": "sha512-0CY3/K54slrzLDjOA7TOjN1NuLKERBgk9nY5V34mhmuu673YNb+7ghaDUs6N0ujXR7fz5XaS5Aa6d2TNxZd0OQ==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
"dev": true,
"license": "MIT", "license": "MIT",
"optional": true, "optional": true,
"os": [ "os": [
@ -8203,13 +8202,12 @@
] ]
}, },
"node_modules/@rollup/rollup-darwin-x64": { "node_modules/@rollup/rollup-darwin-x64": {
"version": "4.41.1", "version": "4.34.9",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.41.1.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.34.9.tgz",
"integrity": "sha512-egpJACny8QOdHNNMZKf8xY0Is6gIMz+tuqXlusxquWu3F833DcMwmGM7WlvCO9sB3OsPjdC4U0wHw5FabzCGZg==", "integrity": "sha512-eOojSEAi/acnsJVYRxnMkPFqcxSMFfrw7r2iD9Q32SGkb/Q9FpUY1UlAu1DH9T7j++gZ0lHjnm4OyH2vCI7l7Q==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
"dev": true,
"license": "MIT", "license": "MIT",
"optional": true, "optional": true,
"os": [ "os": [
@ -8273,13 +8271,12 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-arm64-gnu": { "node_modules/@rollup/rollup-linux-arm64-gnu": {
"version": "4.41.1", "version": "4.34.9",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.41.1.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.34.9.tgz",
"integrity": "sha512-g0UBcNknsmmNQ8V2d/zD2P7WWfJKU0F1nu0k5pW4rvdb+BIqMm8ToluW/eeRmxCared5dD76lS04uL4UaNgpNA==", "integrity": "sha512-6TZjPHjKZUQKmVKMUowF3ewHxctrRR09eYyvT5eFv8w/fXarEra83A2mHTVJLA5xU91aCNOUnM+DWFMSbQ0Nxw==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
"dev": true,
"license": "MIT", "license": "MIT",
"optional": true, "optional": true,
"os": [ "os": [
@ -8287,13 +8284,12 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-arm64-musl": { "node_modules/@rollup/rollup-linux-arm64-musl": {
"version": "4.41.1", "version": "4.34.9",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.41.1.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.34.9.tgz",
"integrity": "sha512-XZpeGB5TKEZWzIrj7sXr+BEaSgo/ma/kCgrZgL0oo5qdB1JlTzIYQKel/RmhT6vMAvOdM2teYlAaOGJpJ9lahg==", "integrity": "sha512-LD2fytxZJZ6xzOKnMbIpgzFOuIKlxVOpiMAXawsAZ2mHBPEYOnLRK5TTEsID6z4eM23DuO88X0Tq1mErHMVq0A==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
"dev": true,
"license": "MIT", "license": "MIT",
"optional": true, "optional": true,
"os": [ "os": [
@ -8371,13 +8367,12 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-x64-gnu": { "node_modules/@rollup/rollup-linux-x64-gnu": {
"version": "4.41.1", "version": "4.34.9",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.41.1.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.34.9.tgz",
"integrity": "sha512-cWBOvayNvA+SyeQMp79BHPK8ws6sHSsYnK5zDcsC3Hsxr1dgTABKjMnMslPq1DvZIp6uO7kIWhiGwaTdR4Og9A==", "integrity": "sha512-FwBHNSOjUTQLP4MG7y6rR6qbGw4MFeQnIBrMe161QGaQoBQLqSUEKlHIiVgF3g/mb3lxlxzJOpIBhaP+C+KP2A==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
"dev": true,
"license": "MIT", "license": "MIT",
"optional": true, "optional": true,
"os": [ "os": [
@ -8385,13 +8380,12 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-x64-musl": { "node_modules/@rollup/rollup-linux-x64-musl": {
"version": "4.41.1", "version": "4.34.9",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.41.1.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.34.9.tgz",
"integrity": "sha512-y5CbN44M+pUCdGDlZFzGGBSKCA4A/J2ZH4edTYSSxFg7ce1Xt3GtydbVKWLlzL+INfFIZAEg1ZV6hh9+QQf9YQ==", "integrity": "sha512-cYRpV4650z2I3/s6+5/LONkjIz8MBeqrk+vPXV10ORBnshpn8S32bPqQ2Utv39jCiDcO2eJTuSlPXpnvmaIgRA==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
"dev": true,
"license": "MIT", "license": "MIT",
"optional": true, "optional": true,
"os": [ "os": [
@ -8399,13 +8393,12 @@
] ]
}, },
"node_modules/@rollup/rollup-win32-arm64-msvc": { "node_modules/@rollup/rollup-win32-arm64-msvc": {
"version": "4.41.1", "version": "4.34.9",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.41.1.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.34.9.tgz",
"integrity": "sha512-lZkCxIrjlJlMt1dLO/FbpZbzt6J/A8p4DnqzSa4PWqPEUUUnzXLeki/iyPLfV0BmHItlYgHUqJe+3KiyydmiNQ==", "integrity": "sha512-z4mQK9dAN6byRA/vsSgQiPeuO63wdiDxZ9yg9iyX2QTzKuQM7T4xlBoeUP/J8uiFkqxkcWndWi+W7bXdPbt27Q==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
"dev": true,
"license": "MIT", "license": "MIT",
"optional": true, "optional": true,
"os": [ "os": [
@ -8427,13 +8420,12 @@
] ]
}, },
"node_modules/@rollup/rollup-win32-x64-msvc": { "node_modules/@rollup/rollup-win32-x64-msvc": {
"version": "4.41.1", "version": "4.34.9",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.41.1.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.34.9.tgz",
"integrity": "sha512-Wq2zpapRYLfi4aKxf2Xff0tN+7slj2d4R87WEzqw7ZLsVvO5zwYCIuEGSZYiK41+GlwUo1HiR+GdkLEJnCKTCw==", "integrity": "sha512-AyleYRPU7+rgkMWbEh71fQlrzRfeP6SyMnRf9XX4fCdDPAJumdSBqYEcWPMzVQ4ScAl7E4oFfK0GUVn77xSwbw==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
"dev": true,
"license": "MIT", "license": "MIT",
"optional": true, "optional": true,
"os": [ "os": [
@ -8848,110 +8840,6 @@
"@rollup/rollup-win32-x64-msvc": "4.34.9" "@rollup/rollup-win32-x64-msvc": "4.34.9"
} }
}, },
"node_modules/@stencil/core/node_modules/@rollup/rollup-darwin-arm64": {
"version": "4.34.9",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.34.9.tgz",
"integrity": "sha512-0CY3/K54slrzLDjOA7TOjN1NuLKERBgk9nY5V34mhmuu673YNb+7ghaDUs6N0ujXR7fz5XaS5Aa6d2TNxZd0OQ==",
"cpu": [
"arm64"
],
"license": "MIT",
"optional": true,
"os": [
"darwin"
]
},
"node_modules/@stencil/core/node_modules/@rollup/rollup-darwin-x64": {
"version": "4.34.9",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.34.9.tgz",
"integrity": "sha512-eOojSEAi/acnsJVYRxnMkPFqcxSMFfrw7r2iD9Q32SGkb/Q9FpUY1UlAu1DH9T7j++gZ0lHjnm4OyH2vCI7l7Q==",
"cpu": [
"x64"
],
"license": "MIT",
"optional": true,
"os": [
"darwin"
]
},
"node_modules/@stencil/core/node_modules/@rollup/rollup-linux-arm64-gnu": {
"version": "4.34.9",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.34.9.tgz",
"integrity": "sha512-6TZjPHjKZUQKmVKMUowF3ewHxctrRR09eYyvT5eFv8w/fXarEra83A2mHTVJLA5xU91aCNOUnM+DWFMSbQ0Nxw==",
"cpu": [
"arm64"
],
"license": "MIT",
"optional": true,
"os": [
"linux"
]
},
"node_modules/@stencil/core/node_modules/@rollup/rollup-linux-arm64-musl": {
"version": "4.34.9",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.34.9.tgz",
"integrity": "sha512-LD2fytxZJZ6xzOKnMbIpgzFOuIKlxVOpiMAXawsAZ2mHBPEYOnLRK5TTEsID6z4eM23DuO88X0Tq1mErHMVq0A==",
"cpu": [
"arm64"
],
"license": "MIT",
"optional": true,
"os": [
"linux"
]
},
"node_modules/@stencil/core/node_modules/@rollup/rollup-linux-x64-gnu": {
"version": "4.34.9",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.34.9.tgz",
"integrity": "sha512-FwBHNSOjUTQLP4MG7y6rR6qbGw4MFeQnIBrMe161QGaQoBQLqSUEKlHIiVgF3g/mb3lxlxzJOpIBhaP+C+KP2A==",
"cpu": [
"x64"
],
"license": "MIT",
"optional": true,
"os": [
"linux"
]
},
"node_modules/@stencil/core/node_modules/@rollup/rollup-linux-x64-musl": {
"version": "4.34.9",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.34.9.tgz",
"integrity": "sha512-cYRpV4650z2I3/s6+5/LONkjIz8MBeqrk+vPXV10ORBnshpn8S32bPqQ2Utv39jCiDcO2eJTuSlPXpnvmaIgRA==",
"cpu": [
"x64"
],
"license": "MIT",
"optional": true,
"os": [
"linux"
]
},
"node_modules/@stencil/core/node_modules/@rollup/rollup-win32-arm64-msvc": {
"version": "4.34.9",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.34.9.tgz",
"integrity": "sha512-z4mQK9dAN6byRA/vsSgQiPeuO63wdiDxZ9yg9iyX2QTzKuQM7T4xlBoeUP/J8uiFkqxkcWndWi+W7bXdPbt27Q==",
"cpu": [
"arm64"
],
"license": "MIT",
"optional": true,
"os": [
"win32"
]
},
"node_modules/@stencil/core/node_modules/@rollup/rollup-win32-x64-msvc": {
"version": "4.34.9",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.34.9.tgz",
"integrity": "sha512-AyleYRPU7+rgkMWbEh71fQlrzRfeP6SyMnRf9XX4fCdDPAJumdSBqYEcWPMzVQ4ScAl7E4oFfK0GUVn77xSwbw==",
"cpu": [
"x64"
],
"license": "MIT",
"optional": true,
"os": [
"win32"
]
},
"node_modules/@surma/rollup-plugin-off-main-thread": { "node_modules/@surma/rollup-plugin-off-main-thread": {
"version": "2.2.3", "version": "2.2.3",
"resolved": "https://registry.npmjs.org/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-2.2.3.tgz", "resolved": "https://registry.npmjs.org/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-2.2.3.tgz",
@ -9556,9 +9444,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/@types/node": { "node_modules/@types/node": {
"version": "20.17.50", "version": "20.17.51",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.50.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.51.tgz",
"integrity": "sha512-Mxiq0ULv/zo1OzOhwPqOA13I81CV/W3nvd3ChtQZRT5Cwz3cr0FKo/wMSsbTqL3EXpaBAEQhva2B8ByRkOIh9A==", "integrity": "sha512-hccptBl7C8lHiKxTBsY6vYYmqpmw1E/aGR/8fmueE+B390L3pdMOpNSRvFO4ZnXzW5+p2HBXV0yNABd2vdk22Q==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"undici-types": "~6.19.2" "undici-types": "~6.19.2"
@ -15403,9 +15291,9 @@
} }
}, },
"node_modules/electron-to-chromium": { "node_modules/electron-to-chromium": {
"version": "1.5.158", "version": "1.5.159",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.158.tgz", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.159.tgz",
"integrity": "sha512-9vcp2xHhkvraY6AHw2WMi+GDSLPX42qe2xjYaVoZqFRJiOcilVQFq9mZmpuHEQpzlgGDelKlV7ZiGcmMsc8WxQ==", "integrity": "sha512-CEvHptWAMV5p6GJ0Lq8aheyvVbfzVrv5mmidu1D3pidoVNkB3tTBsTMVtPJ+rzRK5oV229mCLz9Zj/hNvU8GBA==",
"devOptional": true, "devOptional": true,
"license": "ISC" "license": "ISC"
}, },
@ -16787,9 +16675,9 @@
} }
}, },
"node_modules/fdir": { "node_modules/fdir": {
"version": "6.4.4", "version": "6.4.5",
"resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.4.tgz", "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.5.tgz",
"integrity": "sha512-1NZP+GK4GfuAv3PqKvxQRDMjdSRZjnkq7KfhlNrCNNlZ0ygQFpebfrnfnq/W7fpUnAv9aGWmY1zKx7FYL3gwhg==", "integrity": "sha512-4BG7puHpVsIYxZUbiUE3RqGloLaSSwzYie5jvasC4LWuBWzZawynvYouhjbQKw2JuIGYdm0DzIxl8iVidKlUEw==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"peerDependencies": { "peerDependencies": {
@ -26161,6 +26049,118 @@
"fsevents": "~2.3.2" "fsevents": "~2.3.2"
} }
}, },
"node_modules/rollup/node_modules/@rollup/rollup-darwin-arm64": {
"version": "4.41.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.41.1.tgz",
"integrity": "sha512-5afxvwszzdulsU2w8JKWwY8/sJOLPzf0e1bFuvcW5h9zsEg+RQAojdW0ux2zyYAz7R8HvvzKCjLNJhVq965U7w==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"darwin"
]
},
"node_modules/rollup/node_modules/@rollup/rollup-darwin-x64": {
"version": "4.41.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.41.1.tgz",
"integrity": "sha512-egpJACny8QOdHNNMZKf8xY0Is6gIMz+tuqXlusxquWu3F833DcMwmGM7WlvCO9sB3OsPjdC4U0wHw5FabzCGZg==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"darwin"
]
},
"node_modules/rollup/node_modules/@rollup/rollup-linux-arm64-gnu": {
"version": "4.41.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.41.1.tgz",
"integrity": "sha512-g0UBcNknsmmNQ8V2d/zD2P7WWfJKU0F1nu0k5pW4rvdb+BIqMm8ToluW/eeRmxCared5dD76lS04uL4UaNgpNA==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
]
},
"node_modules/rollup/node_modules/@rollup/rollup-linux-arm64-musl": {
"version": "4.41.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.41.1.tgz",
"integrity": "sha512-XZpeGB5TKEZWzIrj7sXr+BEaSgo/ma/kCgrZgL0oo5qdB1JlTzIYQKel/RmhT6vMAvOdM2teYlAaOGJpJ9lahg==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
]
},
"node_modules/rollup/node_modules/@rollup/rollup-linux-x64-gnu": {
"version": "4.41.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.41.1.tgz",
"integrity": "sha512-cWBOvayNvA+SyeQMp79BHPK8ws6sHSsYnK5zDcsC3Hsxr1dgTABKjMnMslPq1DvZIp6uO7kIWhiGwaTdR4Og9A==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
]
},
"node_modules/rollup/node_modules/@rollup/rollup-linux-x64-musl": {
"version": "4.41.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.41.1.tgz",
"integrity": "sha512-y5CbN44M+pUCdGDlZFzGGBSKCA4A/J2ZH4edTYSSxFg7ce1Xt3GtydbVKWLlzL+INfFIZAEg1ZV6hh9+QQf9YQ==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
]
},
"node_modules/rollup/node_modules/@rollup/rollup-win32-arm64-msvc": {
"version": "4.41.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.41.1.tgz",
"integrity": "sha512-lZkCxIrjlJlMt1dLO/FbpZbzt6J/A8p4DnqzSa4PWqPEUUUnzXLeki/iyPLfV0BmHItlYgHUqJe+3KiyydmiNQ==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"win32"
]
},
"node_modules/rollup/node_modules/@rollup/rollup-win32-x64-msvc": {
"version": "4.41.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.41.1.tgz",
"integrity": "sha512-Wq2zpapRYLfi4aKxf2Xff0tN+7slj2d4R87WEzqw7ZLsVvO5zwYCIuEGSZYiK41+GlwUo1HiR+GdkLEJnCKTCw==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"win32"
]
},
"node_modules/run-con": { "node_modules/run-con": {
"version": "1.3.2", "version": "1.3.2",
"resolved": "https://registry.npmjs.org/run-con/-/run-con-1.3.2.tgz", "resolved": "https://registry.npmjs.org/run-con/-/run-con-1.3.2.tgz",
@ -28355,9 +28355,9 @@
} }
}, },
"node_modules/terser": { "node_modules/terser": {
"version": "5.39.2", "version": "5.40.0",
"resolved": "https://registry.npmjs.org/terser/-/terser-5.39.2.tgz", "resolved": "https://registry.npmjs.org/terser/-/terser-5.40.0.tgz",
"integrity": "sha512-yEPUmWve+VA78bI71BW70Dh0TuV4HHd+I5SHOAfS1+QBOmvmCiiffgjR8ryyEd3KIfvPGFqoADt8LdQ6XpXIvg==", "integrity": "sha512-cfeKl/jjwSR5ar7d0FGmave9hFGJT8obyo0z+CrQOylLDbk7X81nPU6vq9VORa5jU30SkDnT2FXjLbR8HLP+xA==",
"devOptional": true, "devOptional": true,
"license": "BSD-2-Clause", "license": "BSD-2-Clause",
"dependencies": { "dependencies": {
@ -29498,9 +29498,9 @@
} }
}, },
"node_modules/validator": { "node_modules/validator": {
"version": "13.15.0", "version": "13.15.15",
"resolved": "https://registry.npmjs.org/validator/-/validator-13.15.0.tgz", "resolved": "https://registry.npmjs.org/validator/-/validator-13.15.15.tgz",
"integrity": "sha512-36B2ryl4+oL5QxZ3AzD0t5SsMNGvTtQHpjgFO5tbNxfXbMFkY822ktCDe1MnlqV3301QQI9SLHDNJokDI+Z9pA==", "integrity": "sha512-BgWVbCI72aIQy937xbawcs+hrVaN/CZ2UwutgaJ36hGqRrLNM+f5LUT/YPRbo8IV/ASeFzXszezV+y2+rq3l8A==",
"license": "MIT", "license": "MIT",
"engines": { "engines": {
"node": ">= 0.10" "node": ">= 0.10"
@ -30947,9 +30947,9 @@
} }
}, },
"node_modules/zod": { "node_modules/zod": {
"version": "3.25.30", "version": "3.25.32",
"resolved": "https://registry.npmjs.org/zod/-/zod-3.25.30.tgz", "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.32.tgz",
"integrity": "sha512-VolhdEtu6TJr/fzGuHA/SZ5ixvXqA6ADOG9VRcQ3rdOKmF5hkmcJbyaQjUH5BgmpA9gej++zYRX7zjSmdReIwA==", "integrity": "sha512-OSm2xTIRfW8CV5/QKgngwmQW/8aPfGdaQFlrGoErlgg/Epm7cjb6K6VEyExfe65a3VybUOnu381edLb0dfJl0g==",
"license": "MIT", "license": "MIT",
"funding": { "funding": {
"url": "https://github.com/sponsors/colinhacks" "url": "https://github.com/sponsors/colinhacks"

270
scripts/build-electron.js

@ -4,7 +4,6 @@ const path = require('path');
console.log('Starting electron build process...'); console.log('Starting electron build process...');
// Define paths // Define paths
const webDistPath = path.join(__dirname, '..', 'dist');
const electronDistPath = path.join(__dirname, '..', 'dist-electron'); const electronDistPath = path.join(__dirname, '..', 'dist-electron');
const wwwPath = path.join(electronDistPath, 'www'); const wwwPath = path.join(electronDistPath, 'www');
@ -13,8 +12,48 @@ if (!fs.existsSync(wwwPath)) {
fs.mkdirSync(wwwPath, { recursive: true }); fs.mkdirSync(wwwPath, { recursive: true });
} }
// Copy web files to www directory // Create a platform-specific index.html for Electron
fs.cpSync(webDistPath, wwwPath, { recursive: true }); const initialIndexContent = `<!DOCTYPE html>
<html lang="">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0,viewport-fit=cover">
<link rel="icon" href="/favicon.ico">
<title>TimeSafari</title>
</head>
<body>
<noscript>
<strong>We're sorry but TimeSafari doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<script type="module">
// Force electron platform
window.process = { env: { VITE_PLATFORM: 'electron' } };
import('./src/main.electron.ts');
</script>
</body>
</html>`;
// Write the Electron-specific index.html
fs.writeFileSync(path.join(wwwPath, 'index.html'), initialIndexContent);
// Copy only necessary assets from web build
const webDistPath = path.join(__dirname, '..', 'dist');
if (fs.existsSync(webDistPath)) {
// Copy assets directory
const assetsSrc = path.join(webDistPath, 'assets');
const assetsDest = path.join(wwwPath, 'assets');
if (fs.existsSync(assetsSrc)) {
fs.cpSync(assetsSrc, assetsDest, { recursive: true });
}
// Copy favicon
const faviconSrc = path.join(webDistPath, 'favicon.ico');
if (fs.existsSync(faviconSrc)) {
fs.copyFileSync(faviconSrc, path.join(wwwPath, 'favicon.ico'));
}
}
// Remove service worker files // Remove service worker files
const swFilesToRemove = [ const swFilesToRemove = [
@ -88,13 +127,13 @@ if (fs.existsSync(indexPath)) {
// Fix asset paths // Fix asset paths
console.log('Fixing asset paths in index.html...'); console.log('Fixing asset paths in index.html...');
let indexContent = fs.readFileSync(indexPath, 'utf8'); let modifiedIndexContent = fs.readFileSync(indexPath, 'utf8');
indexContent = indexContent modifiedIndexContent = modifiedIndexContent
.replace(/\/assets\//g, './assets/') .replace(/\/assets\//g, './assets/')
.replace(/href="\//g, 'href="./') .replace(/href="\//g, 'href="./')
.replace(/src="\//g, 'src="./'); .replace(/src="\//g, 'src="./');
fs.writeFileSync(indexPath, indexContent); fs.writeFileSync(indexPath, modifiedIndexContent);
// Verify no service worker references remain // Verify no service worker references remain
const finalContent = fs.readFileSync(indexPath, 'utf8'); const finalContent = fs.readFileSync(indexPath, 'utf8');
@ -103,215 +142,24 @@ if (finalContent.includes('serviceWorker') || finalContent.includes('workbox'))
} }
// Check for remaining /assets/ paths // Check for remaining /assets/ paths
console.log('After path fixing, checking for remaining /assets/ paths:', indexContent.includes('/assets/')); console.log('After path fixing, checking for remaining /assets/ paths:', finalContent.includes('/assets/'));
console.log('Sample of fixed content:', indexContent.substring(0, 500)); console.log('Sample of fixed content:', finalContent.substring(0, 500));
console.log('Copied and fixed web files in:', wwwPath); console.log('Copied and fixed web files in:', wwwPath);
// Copy main process files // Copy main process files
console.log('Copying main process files...'); console.log('Copying main process files...');
// Create the main process file with inlined logger
const mainContent = `const { app, BrowserWindow } = require("electron");
const path = require("path");
const fs = require("fs");
// Inline logger implementation // Copy the main process file instead of creating a template
const logger = { const mainSrcPath = path.join(__dirname, '..', 'dist-electron', 'main.js');
log: (...args) => console.log(...args), const mainDestPath = path.join(electronDistPath, 'main.js');
error: (...args) => console.error(...args),
info: (...args) => console.info(...args),
warn: (...args) => console.warn(...args),
debug: (...args) => console.debug(...args),
};
// Check if running in dev mode if (fs.existsSync(mainSrcPath)) {
const isDev = process.argv.includes("--inspect"); fs.copyFileSync(mainSrcPath, mainDestPath);
console.log('Copied main process file successfully');
function createWindow() { } else {
// Add before createWindow function console.error('Main process file not found at:', mainSrcPath);
const preloadPath = path.join(__dirname, "preload.js"); process.exit(1);
logger.log("Checking preload path:", preloadPath);
logger.log("Preload exists:", fs.existsSync(preloadPath));
// Create the browser window.
const mainWindow = new BrowserWindow({
width: 1200,
height: 800,
webPreferences: {
nodeIntegration: false,
contextIsolation: true,
webSecurity: true,
allowRunningInsecureContent: false,
preload: path.join(__dirname, "preload.js"),
},
});
// Always open DevTools for now
mainWindow.webContents.openDevTools();
// Intercept requests to fix asset paths
mainWindow.webContents.session.webRequest.onBeforeRequest(
{
urls: [
"file://*/*/assets/*",
"file://*/assets/*",
"file:///assets/*", // Catch absolute paths
"<all_urls>", // Catch all URLs as a fallback
],
},
(details, callback) => {
let url = details.url;
// Handle paths that don't start with file://
if (!url.startsWith("file://") && url.includes("/assets/")) {
url = \`file://\${path.join(__dirname, "www", url)}\`;
}
// Handle absolute paths starting with /assets/
if (url.includes("/assets/") && !url.includes("/www/assets/")) {
const baseDir = url.includes("dist-electron")
? url.substring(
0,
url.indexOf("/dist-electron") + "/dist-electron".length,
)
: \`file://\${__dirname}\`;
const assetPath = url.split("/assets/")[1];
const newUrl = \`\${baseDir}/www/assets/\${assetPath}\`;
callback({ redirectURL: newUrl });
return;
}
callback({}); // No redirect for other URLs
},
);
if (isDev) {
// Debug info
logger.log("Debug Info:");
logger.log("Running in dev mode:", isDev);
logger.log("App is packaged:", app.isPackaged);
logger.log("Process resource path:", process.resourcesPath);
logger.log("App path:", app.getAppPath());
logger.log("__dirname:", __dirname);
logger.log("process.cwd():", process.cwd());
}
const indexPath = path.join(__dirname, "www", "index.html");
if (isDev) {
logger.log("Loading index from:", indexPath);
logger.log("www path:", path.join(__dirname, "www"));
logger.log("www assets path:", path.join(__dirname, "www", "assets"));
}
if (!fs.existsSync(indexPath)) {
logger.error(\`Index file not found at: \${indexPath}\`);
throw new Error("Index file not found");
}
// Add CSP headers to allow API connections, Google Fonts, and zxing-wasm
mainWindow.webContents.session.webRequest.onHeadersReceived(
(details, callback) => {
callback({
responseHeaders: {
...details.responseHeaders,
"Content-Security-Policy": [
"default-src 'self';" +
"connect-src 'self' https://api.endorser.ch https://*.timesafari.app https://*.jsdelivr.net;" +
"img-src 'self' data: https: blob:;" +
"script-src 'self' 'unsafe-inline' 'unsafe-eval' https://*.jsdelivr.net;" +
"style-src 'self' 'unsafe-inline' https://fonts.googleapis.com;" +
"font-src 'self' data: https://fonts.gstatic.com;" +
"style-src-elem 'self' 'unsafe-inline' https://fonts.googleapis.com;" +
"worker-src 'self' blob:;",
],
},
});
},
);
// Load the index.html
mainWindow
.loadFile(indexPath)
.then(() => {
logger.log("Successfully loaded index.html");
if (isDev) {
mainWindow.webContents.openDevTools();
logger.log("DevTools opened - running in dev mode");
}
})
.catch((err) => {
logger.error("Failed to load index.html:", err);
logger.error("Attempted path:", indexPath);
});
// Listen for console messages from the renderer
mainWindow.webContents.on("console-message", (_event, _level, message) => {
logger.log("Renderer Console:", message);
});
// Add right after creating the BrowserWindow
mainWindow.webContents.on(
"did-fail-load",
(_event, errorCode, errorDescription) => {
logger.error("Page failed to load:", errorCode, errorDescription);
},
);
mainWindow.webContents.on("preload-error", (_event, preloadPath, error) => {
logger.error("Preload script error:", preloadPath, error);
});
mainWindow.webContents.on(
"console-message",
(_event, _level, message, line, sourceId) => {
logger.log("Renderer Console:", line, sourceId, message);
},
);
// Enable remote debugging when in dev mode
if (isDev) {
mainWindow.webContents.openDevTools();
}
} }
// Handle app ready console.log('Electron build process completed successfully');
app.whenReady().then(createWindow);
// Handle all windows closed
app.on("window-all-closed", () => {
if (process.platform !== "darwin") {
app.quit();
}
});
app.on("activate", () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow();
}
});
// Handle any errors
process.on("uncaughtException", (error) => {
logger.error("Uncaught Exception:", error);
});
`;
// Write the main process file
const mainDest = path.join(electronDistPath, 'main.js');
fs.writeFileSync(mainDest, mainContent);
// Copy preload script if it exists
const preloadSrc = path.join(__dirname, '..', 'src', 'electron', 'preload.js');
const preloadDest = path.join(electronDistPath, 'preload.js');
if (fs.existsSync(preloadSrc)) {
console.log(`Copying ${preloadSrc} to ${preloadDest}`);
fs.copyFileSync(preloadSrc, preloadDest);
}
// Verify build structure
console.log('\nVerifying build structure:');
console.log('Files in dist-electron:', fs.readdirSync(electronDistPath));
console.log('Build completed successfully!');

5
src/db-sql/migration.ts

@ -127,10 +127,7 @@ export async function registerMigrations(): Promise<void> {
} }
export async function runMigrations( export async function runMigrations(
sqlExec: ( sqlExec: (sql: string, params?: unknown[]) => Promise<Array<QueryExecResult>>,
sql: string,
params?: unknown[],
) => Promise<Array<QueryExecResult>>,
): Promise<void> { ): Promise<void> {
await registerMigrations(); await registerMigrations();
await migrationService.runMigrations(sqlExec); await migrationService.runMigrations(sqlExec);

86
src/db/databaseUtil.ts

@ -123,35 +123,77 @@ export async function retrieveSettingsForActiveAccount(): Promise<Settings> {
} }
} }
/**
* Logs a message to the database with proper handling of concurrent writes
* @param message - The message to log
* @author Matthew Raymer
*/
export async function logToDb(message: string): Promise<void> { export async function logToDb(message: string): Promise<void> {
const platform = PlatformServiceFactory.getInstance(); const platform = PlatformServiceFactory.getInstance();
const todayKey = new Date().toDateString(); const todayKey = new Date().toDateString();
const fullMessage = `${new Date().toISOString()} ${message}`;
// Check if we have any logs for today try {
const result = await platform.dbQuery( // Try to insert first, if it fails due to UNIQUE constraint, update instead
"SELECT message FROM logs WHERE date = ?", try {
[todayKey], await platform.dbExec("INSERT INTO logs (date, message) VALUES (?, ?)", [
); todayKey,
fullMessage,
]);
} catch (error) {
// If insert fails due to UNIQUE constraint, update instead
if (
error instanceof Error &&
error.message.includes("UNIQUE constraint failed")
) {
const result = await platform.dbQuery(
"SELECT message FROM logs WHERE date = ?",
[todayKey],
);
if (!result || result.values.length === 0) { if (result && result.values.length > 0) {
// If no logs for today, clear all previous logs const prevMessages = result.values[0][0] as string;
await platform.dbExec("DELETE FROM logs"); const updatedMessage = `${prevMessages}\n${fullMessage}`;
// Insert new log await platform.dbExec("UPDATE logs SET message = ? WHERE date = ?", [
const fullMessage = `${new Date().toISOString()} ${message}`; updatedMessage,
await platform.dbExec("INSERT INTO logs (date, message) VALUES (?, ?)", [ todayKey,
todayKey, ]);
fullMessage, }
]); } else {
} else { // If it's a different error, rethrow it
// Append to existing log throw error;
const prevMessages = result.values[0][0] as string; }
const fullMessage = `${prevMessages}\n${new Date().toISOString()} ${message}`; }
await platform.dbExec("UPDATE logs SET message = ? WHERE date = ?", [ // Clean up old logs (keep only last 7 days) - do this less frequently
fullMessage, // Only clean up if the date is different from the last cleanup
todayKey, const lastCleanupKey = "last_log_cleanup";
]); const result = await platform.dbQuery(
"SELECT value FROM settings WHERE key = ?",
[lastCleanupKey],
);
const lastCleanup = result?.values[0]?.[0] as string;
if (!lastCleanup || lastCleanup !== todayKey) {
const sevenDaysAgo = new Date();
sevenDaysAgo.setDate(sevenDaysAgo.getDate() - 7);
await platform.dbExec("DELETE FROM logs WHERE date < ?", [
sevenDaysAgo.toDateString(),
]);
// Update last cleanup date
await platform.dbExec(
"INSERT OR REPLACE INTO settings (key, value) VALUES (?, ?)",
[lastCleanupKey, todayKey],
);
}
} catch (error) {
// Log to console as fallback
// eslint-disable-next-line no-console
console.error("Failed to log to database:", error);
// eslint-disable-next-line no-console
console.error("Original message:", message);
} }
} }

31
src/electron/preload.js

@ -2,24 +2,33 @@ const { contextBridge, ipcRenderer } = require("electron");
const logger = { const logger = {
log: (message, ...args) => { log: (message, ...args) => {
// Always log in development, log with context in production
if (process.env.NODE_ENV !== "production") { if (process.env.NODE_ENV !== "production") {
/* eslint-disable no-console */ /* eslint-disable no-console */
console.log(message, ...args); console.log(`[Preload] ${message}`, ...args);
/* eslint-enable no-console */ /* eslint-enable no-console */
} }
}, },
warn: (message, ...args) => { warn: (message, ...args) => {
if (process.env.NODE_ENV !== "production") { // Always log warnings
/* eslint-disable no-console */ /* eslint-disable no-console */
console.warn(message, ...args); console.warn(`[Preload] ${message}`, ...args);
/* eslint-enable no-console */ /* eslint-enable no-console */
}
}, },
error: (message, ...args) => { error: (message, ...args) => {
// Always log errors
/* eslint-disable no-console */ /* eslint-disable no-console */
console.error(message, ...args); // Errors should always be logged console.error(`[Preload] ${message}`, ...args);
/* eslint-enable no-console */ /* eslint-enable no-console */
}, },
info: (message, ...args) => {
// Always log info in development, log with context in production
if (process.env.NODE_ENV !== "production") {
/* eslint-disable no-console */
console.info(`[Preload] ${message}`, ...args);
/* eslint-enable no-console */
}
},
}; };
// Use a more direct path resolution approach // Use a more direct path resolution approach
@ -41,7 +50,10 @@ const getPath = (pathType) => {
} }
}; };
logger.log("Preload script starting..."); logger.info("Preload script starting...");
// Force electron platform in the renderer process
window.process = { env: { VITE_PLATFORM: "electron" } };
try { try {
contextBridge.exposeInMainWorld("electronAPI", { contextBridge.exposeInMainWorld("electronAPI", {
@ -65,6 +77,7 @@ try {
env: { env: {
isElectron: true, isElectron: true,
isDev: process.env.NODE_ENV === "development", isDev: process.env.NODE_ENV === "development",
platform: "electron", // Explicitly set platform
}, },
// Path utilities // Path utilities
getBasePath: () => { getBasePath: () => {
@ -72,7 +85,7 @@ try {
}, },
}); });
logger.log("Preload script completed successfully"); logger.info("Preload script completed successfully");
} catch (error) { } catch (error) {
logger.error("Error in preload script:", error); logger.error("Error in preload script:", error);
} }

37
src/interfaces/common.ts

@ -43,14 +43,14 @@ export interface KeyMeta {
derivationPath: string; derivationPath: string;
registered?: boolean; registered?: boolean;
profileImageUrl?: string; profileImageUrl?: string;
identity?: string; // Stringified IIdentifier object from Veramo identity?: string; // Stringified IIdentifier object from Veramo
passkeyCredIdHex?: string; // The Webauthn credential ID in hex, if this is from a passkey passkeyCredIdHex?: string; // The Webauthn credential ID in hex, if this is from a passkey
[key: string]: unknown; [key: string]: unknown;
} }
export interface QuantitativeValue extends GenericVerifiableCredential { export interface QuantitativeValue extends GenericVerifiableCredential {
'@type': 'QuantitativeValue'; "@type": "QuantitativeValue";
'@context': string | string[]; "@context": string | string[];
amountOfThisGood: number; amountOfThisGood: number;
unitCode: string; unitCode: string;
[key: string]: unknown; [key: string]: unknown;
@ -101,10 +101,10 @@ export interface Agent {
} }
export interface ClaimObject { export interface ClaimObject {
'@type': string; "@type": string;
'@context'?: string | string[]; "@context"?: string | string[];
fulfills?: Array<{ fulfills?: Array<{
'@type': string; "@type": string;
identifier?: string; identifier?: string;
[key: string]: unknown; [key: string]: unknown;
}>; }>;
@ -119,16 +119,16 @@ export interface ClaimObject {
} }
export interface VerifiableCredentialClaim { export interface VerifiableCredentialClaim {
'@context': string | string[]; "@context": string | string[];
'@type': string; "@type": string;
type: string[]; type: string[];
credentialSubject: ClaimObject; credentialSubject: ClaimObject;
[key: string]: unknown; [key: string]: unknown;
} }
export interface GiveVerifiableCredential extends GenericVerifiableCredential { export interface GiveVerifiableCredential extends GenericVerifiableCredential {
'@type': 'GiveAction'; "@type": "GiveAction";
'@context': string | string[]; "@context": string | string[];
object?: GenericVerifiableCredential; object?: GenericVerifiableCredential;
agent?: Agent; agent?: Agent;
participant?: { participant?: {
@ -136,7 +136,7 @@ export interface GiveVerifiableCredential extends GenericVerifiableCredential {
[key: string]: unknown; [key: string]: unknown;
}; };
fulfills?: Array<{ fulfills?: Array<{
'@type': string; "@type": string;
identifier?: string; identifier?: string;
[key: string]: unknown; [key: string]: unknown;
}>; }>;
@ -144,8 +144,8 @@ export interface GiveVerifiableCredential extends GenericVerifiableCredential {
} }
export interface OfferVerifiableCredential extends GenericVerifiableCredential { export interface OfferVerifiableCredential extends GenericVerifiableCredential {
'@type': 'OfferAction'; "@type": "OfferAction";
'@context': string | string[]; "@context": string | string[];
object?: GenericVerifiableCredential; object?: GenericVerifiableCredential;
agent?: Agent; agent?: Agent;
participant?: { participant?: {
@ -155,7 +155,7 @@ export interface OfferVerifiableCredential extends GenericVerifiableCredential {
itemOffered?: { itemOffered?: {
description?: string; description?: string;
isPartOf?: { isPartOf?: {
'@type': string; "@type": string;
identifier: string; identifier: string;
[key: string]: unknown; [key: string]: unknown;
}; };
@ -164,9 +164,10 @@ export interface OfferVerifiableCredential extends GenericVerifiableCredential {
[key: string]: unknown; [key: string]: unknown;
} }
export interface RegisterVerifiableCredential extends GenericVerifiableCredential { export interface RegisterVerifiableCredential
'@type': 'RegisterAction'; extends GenericVerifiableCredential {
'@context': string | string[]; "@type": "RegisterAction";
"@context": string | string[];
agent: { agent: {
identifier: string; identifier: string;
}; };

18
src/libs/crypto/vc/passkeyDidPeer.ts

@ -194,7 +194,9 @@ export class PeerSetup {
}, },
}; };
const credential = await navigator.credentials.get(options) as PublicKeyCredential; const credential = (await navigator.credentials.get(
options,
)) as PublicKeyCredential;
// console.log("nav credential get", credential); // console.log("nav credential get", credential);
const response = credential?.response as AuthenticatorAssertionResponse; const response = credential?.response as AuthenticatorAssertionResponse;
@ -229,9 +231,7 @@ export class PeerSetup {
.replace(/\//g, "_") .replace(/\//g, "_")
.replace(/=+$/, ""); .replace(/=+$/, "");
const origSignature = Buffer.from(response?.signature).toString( const origSignature = Buffer.from(response?.signature).toString("base64");
"base64",
);
this.signature = origSignature this.signature = origSignature
.replace(/\+/g, "-") .replace(/\+/g, "-")
.replace(/\//g, "_") .replace(/\//g, "_")
@ -327,10 +327,7 @@ export async function verifyJwtP256(
const publicKeyBytes = peerDidToPublicKeyBytes(issuerDid); const publicKeyBytes = peerDidToPublicKeyBytes(issuerDid);
// Use challenge in preimage construction // Use challenge in preimage construction
const preimage = Buffer.concat([ const preimage = Buffer.concat([authDataFromBase, Buffer.from(challenge)]);
authDataFromBase,
Buffer.from(challenge),
]);
const isValid = p256.verify( const isValid = p256.verify(
finalSigBuffer, finalSigBuffer,
@ -391,10 +388,7 @@ export async function verifyJwtWebCrypto(
const finalSigBuffer = unwrapEC2Signature(sigBuffer); const finalSigBuffer = unwrapEC2Signature(sigBuffer);
// Use challenge in preimage construction // Use challenge in preimage construction
const preimage = Buffer.concat([ const preimage = Buffer.concat([authDataFromBase, Buffer.from(challenge)]);
authDataFromBase,
Buffer.from(challenge),
]);
return verifyPeerSignature(preimage, issuerDid, finalSigBuffer); return verifyPeerSignature(preimage, issuerDid, finalSigBuffer);
} }

188
src/libs/endorserServer.ts

@ -53,7 +53,7 @@ import {
ClaimObject, ClaimObject,
VerifiableCredentialClaim, VerifiableCredentialClaim,
Agent, Agent,
QuantitativeValue QuantitativeValue,
} from "../interfaces/common"; } from "../interfaces/common";
import { logger } from "../utils/logger"; import { logger } from "../utils/logger";
import { PlatformServiceFactory } from "@/services/PlatformServiceFactory"; import { PlatformServiceFactory } from "@/services/PlatformServiceFactory";
@ -106,11 +106,12 @@ export const CONTACT_CONFIRM_URL_PATH_TIME_SAFARI = "/contact/confirm/";
*/ */
export const ENDORSER_CH_HANDLE_PREFIX = "https://endorser.ch/entity/"; export const ENDORSER_CH_HANDLE_PREFIX = "https://endorser.ch/entity/";
export const BLANK_GENERIC_SERVER_RECORD: GenericCredWrapper<GenericVerifiableCredential> = { export const BLANK_GENERIC_SERVER_RECORD: GenericCredWrapper<GenericVerifiableCredential> =
claim: { {
"@context": SCHEMA_ORG_CONTEXT, claim: {
"@type": "" "@context": SCHEMA_ORG_CONTEXT,
}, "@type": "",
},
handleId: "", handleId: "",
id: "", id: "",
issuedAt: "", issuedAt: "",
@ -200,10 +201,10 @@ const testRecursivelyOnStrings = (
return input.some((item) => testRecursivelyOnStrings(item, test)); return input.some((item) => testRecursivelyOnStrings(item, test));
} else if (input && typeof input === "object") { } else if (input && typeof input === "object") {
return Object.values(input as Record<string, unknown>).some((value) => return Object.values(input as Record<string, unknown>).some((value) =>
testRecursivelyOnStrings(value, test) testRecursivelyOnStrings(value, test),
); );
} }
return false; return false;
}; };
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
@ -545,7 +546,7 @@ export async function setPlanInCache(
* @returns {string|undefined} User-friendly message or undefined if none found * @returns {string|undefined} User-friendly message or undefined if none found
*/ */
export function serverMessageForUser(error: unknown): string | undefined { export function serverMessageForUser(error: unknown): string | undefined {
if (error && typeof error === 'object' && 'response' in error) { if (error && typeof error === "object" && "response" in error) {
const err = error as AxiosErrorResponse; const err = error as AxiosErrorResponse;
return err.response?.data?.error?.message; return err.response?.data?.error?.message;
} }
@ -571,21 +572,26 @@ export function errorStringForLog(error: unknown) {
// --- property '_value' closes the circle // --- property '_value' closes the circle
} }
let fullError = "" + error + " - JSON: " + stringifiedError; let fullError = "" + error + " - JSON: " + stringifiedError;
if (error && typeof error === 'object' && 'response' in error) { if (error && typeof error === "object" && "response" in error) {
const err = error as AxiosErrorResponse; const err = error as AxiosErrorResponse;
const errorResponseText = JSON.stringify(err.response); const errorResponseText = JSON.stringify(err.response);
// for some reason, error.response is not included in stringify result (eg. for 400 errors on invite redemptions) // for some reason, error.response is not included in stringify result (eg. for 400 errors on invite redemptions)
if (!R.empty(errorResponseText) && !fullError.includes(errorResponseText)) { if (!R.empty(errorResponseText) && !fullError.includes(errorResponseText)) {
// add error.response stuff // add error.response stuff
if (err.response?.config && err.config && R.equals(err.config, err.response.config)) { if (
// but exclude "config" because it's already in there err.response?.config &&
const newErrorResponseText = JSON.stringify( err.config &&
R.equals(err.config, err.response.config)
) {
// but exclude "config" because it's already in there
const newErrorResponseText = JSON.stringify(
R.omit(["config"] as never[], err.response), R.omit(["config"] as never[], err.response),
); );
fullError += " - .response w/o same config JSON: " + newErrorResponseText; fullError +=
} else { " - .response w/o same config JSON: " + newErrorResponseText;
fullError += " - .response JSON: " + errorResponseText; } else {
fullError += " - .response JSON: " + errorResponseText;
} }
} }
} }
@ -664,7 +670,7 @@ export function hydrateGive(
"@type": "GiveAction", "@type": "GiveAction",
object: undefined, object: undefined,
agent: undefined, agent: undefined,
fulfills: [] fulfills: [],
}; };
if (lastClaimId) { if (lastClaimId) {
@ -679,13 +685,13 @@ export function hydrateGive(
vcClaim.recipient = { identifier: toDid }; vcClaim.recipient = { identifier: toDid };
} }
vcClaim.description = description || undefined; vcClaim.description = description || undefined;
if (amount && !isNaN(amount)) { if (amount && !isNaN(amount)) {
const quantitativeValue: QuantitativeValue = { const quantitativeValue: QuantitativeValue = {
"@context": SCHEMA_ORG_CONTEXT, "@context": SCHEMA_ORG_CONTEXT,
"@type": "QuantitativeValue", "@type": "QuantitativeValue",
amountOfThisGood: amount, amountOfThisGood: amount,
unitCode: unitCode || "HUR" unitCode: unitCode || "HUR",
}; };
vcClaim.object = quantitativeValue; vcClaim.object = quantitativeValue;
} }
@ -697,34 +703,34 @@ export function hydrateGive(
// Filter and add fulfills elements // Filter and add fulfills elements
vcClaim.fulfills = vcClaim.fulfills.filter( vcClaim.fulfills = vcClaim.fulfills.filter(
(elem: { '@type': string }) => elem["@type"] !== "PlanAction" (elem: { "@type": string }) => elem["@type"] !== "PlanAction",
); );
if (fulfillsProjectHandleId) { if (fulfillsProjectHandleId) {
vcClaim.fulfills.push({ vcClaim.fulfills.push({
"@type": "PlanAction", "@type": "PlanAction",
identifier: fulfillsProjectHandleId identifier: fulfillsProjectHandleId,
}); });
} }
vcClaim.fulfills = vcClaim.fulfills.filter( vcClaim.fulfills = vcClaim.fulfills.filter(
(elem: { '@type': string }) => elem["@type"] !== "Offer" (elem: { "@type": string }) => elem["@type"] !== "Offer",
); );
if (fulfillsOfferHandleId) { if (fulfillsOfferHandleId) {
vcClaim.fulfills.push({ vcClaim.fulfills.push({
"@type": "Offer", "@type": "Offer",
identifier: fulfillsOfferHandleId identifier: fulfillsOfferHandleId,
}); });
} }
vcClaim.fulfills = vcClaim.fulfills.filter( vcClaim.fulfills = vcClaim.fulfills.filter(
(elem: { '@type': string }) => (elem: { "@type": string }) =>
elem["@type"] !== "DonateAction" && elem["@type"] !== "TradeAction" elem["@type"] !== "DonateAction" && elem["@type"] !== "TradeAction",
); );
vcClaim.fulfills.push({ vcClaim.fulfills.push({
"@type": isTrade ? "TradeAction" : "DonateAction" "@type": isTrade ? "TradeAction" : "DonateAction",
}); });
vcClaim.image = imageUrl || undefined; vcClaim.image = imageUrl || undefined;
@ -732,7 +738,7 @@ export function hydrateGive(
if (providerPlanHandleId) { if (providerPlanHandleId) {
vcClaim.provider = { vcClaim.provider = {
"@type": "PlanAction", "@type": "PlanAction",
identifier: providerPlanHandleId identifier: providerPlanHandleId,
}; };
} }
@ -854,7 +860,7 @@ export function hydrateOffer(
"@type": "OfferAction", "@type": "OfferAction",
object: undefined, object: undefined,
agent: undefined, agent: undefined,
itemOffered: {} itemOffered: {},
}; };
if (lastClaimId) { if (lastClaimId) {
@ -875,7 +881,7 @@ export function hydrateOffer(
"@context": SCHEMA_ORG_CONTEXT, "@context": SCHEMA_ORG_CONTEXT,
"@type": "QuantitativeValue", "@type": "QuantitativeValue",
amountOfThisGood: amount, amountOfThisGood: amount,
unitCode: unitCode || "HUR" unitCode: unitCode || "HUR",
}; };
vcClaim.object = quantitativeValue; vcClaim.object = quantitativeValue;
} }
@ -886,7 +892,7 @@ export function hydrateOffer(
if (fulfillsProjectHandleId) { if (fulfillsProjectHandleId) {
vcClaim.itemOffered.isPartOf = { vcClaim.itemOffered.isPartOf = {
"@type": "PlanAction", "@type": "PlanAction",
identifier: fulfillsProjectHandleId identifier: fulfillsProjectHandleId,
}; };
} }
} }
@ -1024,12 +1030,14 @@ export async function createAndSubmitClaim(
logger.error("Error submitting claim:", error); logger.error("Error submitting claim:", error);
const errorMessage: string = const errorMessage: string =
serverMessageForUser(error) || serverMessageForUser(error) ||
(error && typeof error === 'object' && 'message' in error ? String(error.message) : undefined) || (error && typeof error === "object" && "message" in error
? String(error.message)
: undefined) ||
"Got some error submitting the claim. Check your permissions, network, and error logs."; "Got some error submitting the claim. Check your permissions, network, and error logs.";
return { return {
success: false, success: false,
error: errorMessage error: errorMessage,
}; };
} }
} }
@ -1061,10 +1069,7 @@ export async function generateEndorserJwtUrlForAccount(
// Add the next key -- not recommended for the QR code for such a high resolution // Add the next key -- not recommended for the QR code for such a high resolution
if (isContact) { if (isContact) {
const newDerivPath = nextDerivationPath(account.derivationPath); const newDerivPath = nextDerivationPath(account.derivationPath);
const nextPublicHex = deriveAddress( const nextPublicHex = deriveAddress(account.mnemonic, newDerivPath)[2];
account.mnemonic,
newDerivPath,
)[2];
const nextPublicEncKey = Buffer.from(nextPublicHex, "hex"); const nextPublicEncKey = Buffer.from(nextPublicHex, "hex");
const nextPublicEncKeyHash = sha256(nextPublicEncKey); const nextPublicEncKeyHash = sha256(nextPublicEncKey);
const nextPublicEncKeyHashBase64 = const nextPublicEncKeyHashBase64 =
@ -1133,13 +1138,15 @@ export const capitalizeAndInsertSpacesBeforeCaps = (text: string) => {
similar code is also contained in endorser-mobile similar code is also contained in endorser-mobile
**/ **/
const claimSummary = ( const claimSummary = (
claim: GenericVerifiableCredential | GenericCredWrapper<GenericVerifiableCredential>, claim:
| GenericVerifiableCredential
| GenericCredWrapper<GenericVerifiableCredential>,
) => { ) => {
if (!claim) { if (!claim) {
return "something"; return "something";
} }
let specificClaim: GenericVerifiableCredential; let specificClaim: GenericVerifiableCredential;
if ('claim' in claim) { if ("claim" in claim) {
// It's a GenericCredWrapper // It's a GenericCredWrapper
specificClaim = claim.claim as GenericVerifiableCredential; specificClaim = claim.claim as GenericVerifiableCredential;
} else { } else {
@ -1180,7 +1187,7 @@ export const claimSpecialDescription = (
contacts: Array<Contact>, contacts: Array<Contact>,
) => { ) => {
let claim = record.claim; let claim = record.claim;
if ('claim' in claim) { if ("claim" in claim) {
claim = claim.claim as GenericVerifiableCredential; claim = claim.claim as GenericVerifiableCredential;
} }
@ -1189,12 +1196,23 @@ export const claimSpecialDescription = (
const type = claimObj["@type"] || "UnknownType"; const type = claimObj["@type"] || "UnknownType";
if (type === "AgreeAction") { if (type === "AgreeAction") {
return issuer + " agreed with " + claimSummary(claimObj.object as GenericVerifiableCredential); return (
issuer +
" agreed with " +
claimSummary(claimObj.object as GenericVerifiableCredential)
);
} else if (isAccept(claim)) { } else if (isAccept(claim)) {
return issuer + " accepted " + claimSummary(claimObj.object as GenericVerifiableCredential); return (
issuer +
" accepted " +
claimSummary(claimObj.object as GenericVerifiableCredential)
);
} else if (type === "GiveAction") { } else if (type === "GiveAction") {
const giveClaim = claim as GiveVerifiableCredential; const giveClaim = claim as GiveVerifiableCredential;
const agent: Agent = giveClaim.agent || { identifier: undefined, did: undefined }; const agent: Agent = giveClaim.agent || {
identifier: undefined,
did: undefined,
};
const agentDid = agent.did || agent.identifier; const agentDid = agent.did || agent.identifier;
const contactInfo = agentDid const contactInfo = agentDid
? didInfo(agentDid, activeDid, identifiers, contacts) ? didInfo(agentDid, activeDid, identifiers, contacts)
@ -1209,7 +1227,10 @@ export const claimSpecialDescription = (
return contactInfo + " gave" + offering + recipientInfo; return contactInfo + " gave" + offering + recipientInfo;
} else if (type === "JoinAction") { } else if (type === "JoinAction") {
const joinClaim = claim as ClaimObject; const joinClaim = claim as ClaimObject;
const agent: Agent = joinClaim.agent || { identifier: undefined, did: undefined }; const agent: Agent = joinClaim.agent || {
identifier: undefined,
did: undefined,
};
const agentDid = agent.did || agent.identifier; const agentDid = agent.did || agent.identifier;
const contactInfo = agentDid const contactInfo = agentDid
? didInfo(agentDid, activeDid, identifiers, contacts) ? didInfo(agentDid, activeDid, identifiers, contacts)
@ -1219,7 +1240,10 @@ export const claimSpecialDescription = (
return contactInfo + " joined" + objectInfo; return contactInfo + " joined" + objectInfo;
} else if (isOffer(claim)) { } else if (isOffer(claim)) {
const offerClaim = claim as OfferVerifiableCredential; const offerClaim = claim as OfferVerifiableCredential;
const agent: Agent = offerClaim.agent || { identifier: undefined, did: undefined }; const agent: Agent = offerClaim.agent || {
identifier: undefined,
did: undefined,
};
const agentDid = agent.did || agent.identifier; const agentDid = agent.did || agent.identifier;
const contactInfo = agentDid const contactInfo = agentDid
? didInfo(agentDid, activeDid, identifiers, contacts) ? didInfo(agentDid, activeDid, identifiers, contacts)
@ -1234,7 +1258,10 @@ export const claimSpecialDescription = (
return contactInfo + " offered" + offering + offerRecipientInfo; return contactInfo + " offered" + offering + offerRecipientInfo;
} else if (type === "PlanAction") { } else if (type === "PlanAction") {
const planClaim = claim as ClaimObject; const planClaim = claim as ClaimObject;
const agent: Agent = planClaim.agent || { identifier: undefined, did: undefined }; const agent: Agent = planClaim.agent || {
identifier: undefined,
did: undefined,
};
const agentDid = agent.did || agent.identifier; const agentDid = agent.did || agent.identifier;
const contactInfo = agentDid const contactInfo = agentDid
? didInfo(agentDid, activeDid, identifiers, contacts) ? didInfo(agentDid, activeDid, identifiers, contacts)
@ -1244,7 +1271,10 @@ export const claimSpecialDescription = (
return contactInfo + " planned" + objectInfo; return contactInfo + " planned" + objectInfo;
} else if (type === "Tenure") { } else if (type === "Tenure") {
const tenureClaim = claim as ClaimObject; const tenureClaim = claim as ClaimObject;
const agent: Agent = tenureClaim.agent || { identifier: undefined, did: undefined }; const agent: Agent = tenureClaim.agent || {
identifier: undefined,
did: undefined,
};
const agentDid = agent.did || agent.identifier; const agentDid = agent.did || agent.identifier;
const contactInfo = agentDid const contactInfo = agentDid
? didInfo(agentDid, activeDid, identifiers, contacts) ? didInfo(agentDid, activeDid, identifiers, contacts)
@ -1253,11 +1283,7 @@ export const claimSpecialDescription = (
const objectInfo = object ? " " + claimSummary(object) : ""; const objectInfo = object ? " " + claimSummary(object) : "";
return contactInfo + " has tenure" + objectInfo; return contactInfo + " has tenure" + objectInfo;
} else { } else {
return ( return issuer + " declared " + claimSummary(claim);
issuer +
" declared " +
claimSummary(claim)
);
} }
}; };
@ -1333,35 +1359,39 @@ export async function register(
contact: Contact, contact: Contact,
): Promise<{ success?: boolean; error?: string }> { ): Promise<{ success?: boolean; error?: string }> {
try { try {
const vcJwt = await createInviteJwt(activeDid, contact); const vcJwt = await createInviteJwt(activeDid, contact);
const url = apiServer + "/api/v2/claim"; const url = apiServer + "/api/v2/claim";
const resp = await axios.post<{ const resp = await axios.post<{
success?: { success?: {
handleId?: string; handleId?: string;
embeddedRecordError?: string; embeddedRecordError?: string;
}; };
error?: string; error?: string;
message?: string; message?: string;
}>(url, { jwtEncoded: vcJwt }); }>(url, { jwtEncoded: vcJwt });
if (resp.data?.success?.handleId) { if (resp.data?.success?.handleId) {
return { success: true }; return { success: true };
} else if (resp.data?.success?.embeddedRecordError) { } else if (resp.data?.success?.embeddedRecordError) {
let message = "There was some problem with the registration and so it may not be complete."; let message =
"There was some problem with the registration and so it may not be complete.";
if (typeof resp.data.success.embeddedRecordError === "string") { if (typeof resp.data.success.embeddedRecordError === "string") {
message += " " + resp.data.success.embeddedRecordError; message += " " + resp.data.success.embeddedRecordError;
} }
return { error: message }; return { error: message };
} else { } else {
logger.error("Registration error:", JSON.stringify(resp.data)); logger.error("Registration error:", JSON.stringify(resp.data));
return { error: "Got a server error when registering." }; return { error: "Got a server error when registering." };
} }
} catch (error: unknown) { } catch (error: unknown) {
if (error && typeof error === 'object') { if (error && typeof error === "object") {
const err = error as AxiosErrorResponse; const err = error as AxiosErrorResponse;
const errorMessage = err.message || const errorMessage =
(err.response?.data && typeof err.response.data === 'object' && 'message' in err.response.data err.message ||
? (err.response.data as { message: string }).message (err.response?.data &&
typeof err.response.data === "object" &&
"message" in err.response.data
? (err.response.data as { message: string }).message
: undefined); : undefined);
logger.error("Registration error:", errorMessage || JSON.stringify(err)); logger.error("Registration error:", errorMessage || JSON.stringify(err));
return { error: errorMessage || "Got a server error when registering." }; return { error: errorMessage || "Got a server error when registering." };

27
src/libs/util.ts

@ -30,19 +30,13 @@ import {
simpleEncrypt, simpleEncrypt,
} from "../libs/crypto"; } from "../libs/crypto";
import * as serverUtil from "../libs/endorserServer"; import * as serverUtil from "../libs/endorserServer";
import { import { containsHiddenDid } from "../libs/endorserServer";
containsHiddenDid,
} from "../libs/endorserServer";
import { import {
GenericCredWrapper, GenericCredWrapper,
GenericVerifiableCredential, GenericVerifiableCredential,
} from "../interfaces/common"; } from "../interfaces/common";
import { import { GiveSummaryRecord } from "../interfaces/records";
GiveSummaryRecord, import { OfferVerifiableCredential } from "../interfaces/claims";
} from "../interfaces/records";
import {
OfferVerifiableCredential,
} from "../interfaces/claims";
import { KeyMeta } from "../interfaces/common"; import { KeyMeta } from "../interfaces/common";
import { createPeerDid } from "../libs/crypto/vc/didPeer"; import { createPeerDid } from "../libs/crypto/vc/didPeer";
import { registerCredential } from "../libs/crypto/vc/passkeyDidPeer"; import { registerCredential } from "../libs/crypto/vc/passkeyDidPeer";
@ -406,10 +400,7 @@ export function offerGiverDid(
export const canFulfillOffer = ( export const canFulfillOffer = (
veriClaim: GenericCredWrapper<GenericVerifiableCredential>, veriClaim: GenericCredWrapper<GenericVerifiableCredential>,
) => { ) => {
return ( return veriClaim.claimType === "Offer" && !!offerGiverDid(veriClaim);
veriClaim.claimType === "Offer" &&
!!offerGiverDid(veriClaim)
);
}; };
// return object with paths and arrays of DIDs for any keys ending in "VisibleToDid" // return object with paths and arrays of DIDs for any keys ending in "VisibleToDid"
@ -478,8 +469,10 @@ export function findAllVisibleToDids(
* *
**/ **/
export interface AccountKeyInfo extends Omit<Account, 'derivationPath'>, Omit<KeyMeta, 'derivationPath'> { export interface AccountKeyInfo
derivationPath?: string; // Make it optional to match Account type extends Omit<Account, "derivationPath">,
Omit<KeyMeta, "derivationPath"> {
derivationPath?: string; // Make it optional to match Account type
} }
export const retrieveAccountCount = async (): Promise<number> => { export const retrieveAccountCount = async (): Promise<number> => {
@ -489,7 +482,7 @@ export const retrieveAccountCount = async (): Promise<number> => {
`SELECT COUNT(*) FROM accounts`, `SELECT COUNT(*) FROM accounts`,
); );
if (dbResult?.values?.[0]?.[0]) { if (dbResult?.values?.[0]?.[0]) {
result = dbResult.values[0][0] as number; result = dbResult.values[0][0] as number;
} }
if (USE_DEXIE_DB) { if (USE_DEXIE_DB) {
@ -638,7 +631,7 @@ export const retrieveAllFullyDecryptedAccounts = async (): Promise<
) as unknown as AccountEncrypted[]; ) as unknown as AccountEncrypted[];
if (USE_DEXIE_DB) { if (USE_DEXIE_DB) {
const accountsDB = await accountsDBPromise; const accountsDB = await accountsDBPromise;
allAccounts = await accountsDB.accounts.toArray() as AccountEncrypted[]; allAccounts = (await accountsDB.accounts.toArray()) as AccountEncrypted[];
} }
return allAccounts; return allAccounts;
}; };

6
src/main.common.ts

@ -10,6 +10,12 @@ import { FontAwesomeIcon } from "./libs/fontawesome";
import Camera from "simple-vue-camera"; import Camera from "simple-vue-camera";
import { logger } from "./utils/logger"; import { logger } from "./utils/logger";
const platform = process.env.VITE_PLATFORM;
const pwa_enabled = process.env.VITE_PWA_ENABLED === "true";
logger.error("Platform", { platform });
logger.error("PWA enabled", { pwa_enabled });
// Global Error Handler // Global Error Handler
function setupGlobalErrorHandler(app: VueApp) { function setupGlobalErrorHandler(app: VueApp) {
logger.log("[App Init] Setting up global error handler"); logger.log("[App Init] Setting up global error handler");

12
src/main.electron.ts

@ -1,4 +1,16 @@
import { initializeApp } from "./main.common"; import { initializeApp } from "./main.common";
import { logger } from "./utils/logger";
const platform = process.env.VITE_PLATFORM;
const pwa_enabled = process.env.VITE_PWA_ENABLED === "true";
logger.info("[Electron] Initializing app");
logger.info("[Electron] Platform:", { platform });
logger.info("[Electron] PWA enabled:", { pwa_enabled });
if (pwa_enabled) {
logger.warn("[Electron] PWA is enabled, but not supported in electron");
}
const app = initializeApp(); const app = initializeApp();
app.mount("#app"); app.mount("#app");

18
src/main.web.ts

@ -1,11 +1,15 @@
import { initBackend } from "absurd-sql/dist/indexeddb-main-thread"; import { initBackend } from "absurd-sql/dist/indexeddb-main-thread";
import { initializeApp } from "./main.common"; import { initializeApp } from "./main.common";
import { logger } from "./utils/logger";
const platform = process.env.VITE_PLATFORM;
const pwa_enabled = process.env.VITE_PWA_ENABLED === "true";
logger.error("[Web] PWA enabled", { pwa_enabled });
logger.error("[Web] Platform", { platform });
// Only import service worker for web builds // Only import service worker for web builds
if ( if (platform !== "electron" && pwa_enabled) {
process.env.VITE_PLATFORM !== "electron" &&
process.env.VITE_PWA_ENABLED === "true"
) {
import("./registerServiceWorker"); // Web PWA support import("./registerServiceWorker"); // Web PWA support
} }
@ -24,6 +28,10 @@ function sqlInit() {
// workers through the main thread // workers through the main thread
initBackend(worker); initBackend(worker);
} }
sqlInit(); if (platform === "web" || platform === "development") {
sqlInit();
} else {
logger.info("[Web] SQL not initialized for platform", { platform });
}
app.mount("#app"); app.mount("#app");

4
src/services/AbsurdSqlDatabaseService.ts

@ -22,12 +22,12 @@ interface AbsurdSqlDatabase {
) => Promise<{ changes: number; lastId?: number }>; ) => Promise<{ changes: number; lastId?: number }>;
} }
class AbsurdSqlDatabaseService implements DatabaseService { class AbsurdSqlDatabaseService<T> implements DatabaseService {
private static instance: AbsurdSqlDatabaseService | null = null; private static instance: AbsurdSqlDatabaseService | null = null;
private db: AbsurdSqlDatabase | null; private db: AbsurdSqlDatabase | null;
private initialized: boolean; private initialized: boolean;
private initializationPromise: Promise<void> | null = null; private initializationPromise: Promise<void> | null = null;
private operationQueue: Array<QueuedOperation<any>> = []; private operationQueue: Array<QueuedOperation<T>> = [];
private isProcessingQueue: boolean = false; private isProcessingQueue: boolean = false;
private constructor() { private constructor() {

13
src/services/QRScanner/CapacitorQRScanner.ts

@ -4,7 +4,13 @@ import {
StartScanOptions, StartScanOptions,
LensFacing, LensFacing,
} from "@capacitor-mlkit/barcode-scanning"; } from "@capacitor-mlkit/barcode-scanning";
import { QRScannerService, ScanListener, QRScannerOptions, CameraStateListener, CameraState } from "./types"; import {
QRScannerService,
ScanListener,
QRScannerOptions,
CameraStateListener,
CameraState,
} from "./types";
import { logger } from "@/utils/logger"; import { logger } from "@/utils/logger";
export class CapacitorQRScanner implements QRScannerService { export class CapacitorQRScanner implements QRScannerService {
@ -96,7 +102,10 @@ export class CapacitorQRScanner implements QRScannerService {
// Check if scanning is supported // Check if scanning is supported
if (!(await this.isSupported())) { if (!(await this.isSupported())) {
this.updateCameraState("error", "QR scanning not supported on this device"); this.updateCameraState(
"error",
"QR scanning not supported on this device",
);
throw new Error("QR scanning not supported on this device"); throw new Error("QR scanning not supported on this device");
} }

5
src/services/QRScanner/WebInlineQRScanner.ts

@ -512,7 +512,10 @@ export class WebInlineQRScanner implements QRScannerService {
this.scanAttempts = 0; this.scanAttempts = 0;
this.lastScanTime = Date.now(); this.lastScanTime = Date.now();
this.updateCameraState("initializing", "Starting camera..."); this.updateCameraState("initializing", "Starting camera...");
logger.error(`[WebInlineQRScanner:${this.id}] Starting scan with options:`, this.options); logger.error(
`[WebInlineQRScanner:${this.id}] Starting scan with options:`,
this.options,
);
// Get camera stream with options // Get camera stream with options
logger.error( logger.error(

6
src/services/deepLinks.ts

@ -121,10 +121,10 @@ export class DeepLinkHandler {
// Validate route exists before proceeding // Validate route exists before proceeding
if (!this.ROUTE_MAP[routePath]) { if (!this.ROUTE_MAP[routePath]) {
throw { throw {
code: "INVALID_ROUTE", code: "INVALID_ROUTE",
message: `Invalid route path: ${routePath}`, message: `Invalid route path: ${routePath}`,
details: { routePath } details: { routePath },
}; };
} }

6
src/utils/logger.ts

@ -42,7 +42,8 @@ export const logger = {
info: (message: string, ...args: unknown[]) => { info: (message: string, ...args: unknown[]) => {
if ( if (
process.env.NODE_ENV !== "production" || process.env.NODE_ENV !== "production" ||
process.env.VITE_PLATFORM === "capacitor" process.env.VITE_PLATFORM === "capacitor" ||
process.env.VITE_PLATFORM === "electron"
) { ) {
// eslint-disable-next-line no-console // eslint-disable-next-line no-console
console.info(message, ...args); console.info(message, ...args);
@ -53,7 +54,8 @@ export const logger = {
warn: (message: string, ...args: unknown[]) => { warn: (message: string, ...args: unknown[]) => {
if ( if (
process.env.NODE_ENV !== "production" || process.env.NODE_ENV !== "production" ||
process.env.VITE_PLATFORM === "capacitor" process.env.VITE_PLATFORM === "capacitor" ||
process.env.VITE_PLATFORM === "electron"
) { ) {
// eslint-disable-next-line no-console // eslint-disable-next-line no-console
console.warn(message, ...args); console.warn(message, ...args);

4
src/views/ContactsView.vue

@ -995,8 +995,8 @@ export default class ContactsView extends Vue {
newContact as unknown as Record<string, unknown>, newContact as unknown as Record<string, unknown>,
"contacts", "contacts",
); );
console.log("sql", sql); logger.error("sql", sql);
console.log("params", params); logger.error("params", params);
let contactPromise = platformService.dbExec(sql, params); let contactPromise = platformService.dbExec(sql, params);
if (USE_DEXIE_DB) { if (USE_DEXIE_DB) {
// @ts-expect-error since the result of this promise won't be used, and this will go away soon // @ts-expect-error since the result of this promise won't be used, and this will go away soon

3
src/views/ImportAccountView.vue

@ -90,15 +90,12 @@ import { AppString, NotificationIface, USE_DEXIE_DB } from "../constants/app";
import * as databaseUtil from "../db/databaseUtil"; import * as databaseUtil from "../db/databaseUtil";
import { import {
accountsDBPromise, accountsDBPromise,
db,
retrieveSettingsForActiveAccount, retrieveSettingsForActiveAccount,
} from "../db/index"; } from "../db/index";
import { MASTER_SETTINGS_KEY } from "../db/tables/settings";
import { import {
DEFAULT_ROOT_DERIVATION_PATH, DEFAULT_ROOT_DERIVATION_PATH,
deriveAddress, deriveAddress,
newIdentifier, newIdentifier,
simpleEncrypt,
} from "../libs/crypto"; } from "../libs/crypto";
import { retrieveAccountCount, saveNewIdentity } from "../libs/util"; import { retrieveAccountCount, saveNewIdentity } from "../libs/util";
import { PlatformServiceFactory } from "@/services/PlatformServiceFactory"; import { PlatformServiceFactory } from "@/services/PlatformServiceFactory";

Loading…
Cancel
Save