@proteinjs/user-server 1.5.3 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +25 -0
- package/LICENSE +21 -0
- package/dist/generated/index.d.ts +1 -4
- package/dist/generated/index.d.ts.map +1 -1
- package/dist/generated/index.js +6 -7
- package/dist/generated/index.js.map +1 -1
- package/dist/src/authentication/DbSessionStore.d.ts +0 -1
- package/dist/src/authentication/DbSessionStore.d.ts.map +1 -1
- package/dist/src/routes/avatar.d.ts +19 -0
- package/dist/src/routes/avatar.d.ts.map +1 -0
- package/dist/src/routes/avatar.js +108 -0
- package/dist/src/routes/avatar.js.map +1 -0
- package/dist/src/routes/devLogin.d.ts.map +1 -1
- package/dist/src/routes/devLogin.js +11 -0
- package/dist/src/routes/devLogin.js.map +1 -1
- package/dist/src/services/UpdateUserInfo.d.ts +40 -2
- package/dist/src/services/UpdateUserInfo.d.ts.map +1 -1
- package/dist/src/services/UpdateUserInfo.js +183 -12
- package/dist/src/services/UpdateUserInfo.js.map +1 -1
- package/dist/test/UpdateUserInfoAvatar.test.d.ts +2 -0
- package/dist/test/UpdateUserInfoAvatar.test.d.ts.map +1 -0
- package/dist/test/UpdateUserInfoAvatar.test.js +337 -0
- package/dist/test/UpdateUserInfoAvatar.test.js.map +1 -0
- package/dist/test/UpdateUserInfoSessionRefresh.test.d.ts +2 -0
- package/dist/test/UpdateUserInfoSessionRefresh.test.d.ts.map +1 -0
- package/dist/test/UpdateUserInfoSessionRefresh.test.js +94 -0
- package/dist/test/UpdateUserInfoSessionRefresh.test.js.map +1 -0
- package/dist/test/UserServerTestEnvironment.d.ts +26 -0
- package/dist/test/UserServerTestEnvironment.d.ts.map +1 -0
- package/dist/test/UserServerTestEnvironment.js +202 -0
- package/dist/test/UserServerTestEnvironment.js.map +1 -0
- package/dist/test/avatarRoute.test.d.ts +2 -0
- package/dist/test/avatarRoute.test.d.ts.map +1 -0
- package/dist/test/avatarRoute.test.js +222 -0
- package/dist/test/avatarRoute.test.js.map +1 -0
- package/generated/index.ts +21 -25
- package/jest.config.js +4 -1
- package/package.json +9 -5
- package/src/heic-decode.d.ts +13 -0
- package/src/routes/avatar.ts +57 -0
- package/src/routes/devLogin.ts +5 -0
- package/src/services/UpdateUserInfo.ts +124 -13
- package/test/UpdateUserInfoAvatar.test.ts +174 -0
- package/test/UpdateUserInfoSessionRefresh.test.ts +37 -0
- package/test/UserServerTestEnvironment.ts +97 -0
- package/test/avatarRoute.test.ts +111 -0
- package/test/emulatorLock.globalSetup.js +11 -0
- package/test/emulatorLock.globalTeardown.js +8 -0
- package/test/emulatorLock.js +124 -0
- package/test/fixtures/fixture.heic +0 -0
- package/tsconfig.json +1 -0
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,31 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
# [1.6.0](https://github.com/proteinjs/user/compare/@proteinjs/user-server@1.5.4...@proteinjs/user-server@1.6.0) (2026-08-14)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Bug Fixes
|
|
10
|
+
|
|
11
|
+
* await session save in devLogin before redirecting ([c7476c8](https://github.com/proteinjs/user/commit/c7476c83a0ad760a9caf55e8d06e2edef9e0f1ac))
|
|
12
|
+
* dedupe setupFiles in user-server jest config — merge artifact, both keys named the same setup module ([085a041](https://github.com/proteinjs/user/commit/085a0415397e93354a9aef2d00f24eacf2c13733))
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
### Features
|
|
16
|
+
|
|
17
|
+
* user avatars — photo/emoji schema, avatar mutations with session-cache refresh, shared /avatar route ([6af0bc5](https://github.com/proteinjs/user/commit/6af0bc5b34cf42fc3cc47706fc200fd8fdaa8d8d))
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
## [1.5.4](https://github.com/proteinjs/user/compare/@proteinjs/user-server@1.5.3...@proteinjs/user-server@1.5.4) (2026-08-14)
|
|
24
|
+
|
|
25
|
+
**Note:** Version bump only for package @proteinjs/user-server
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
|
|
6
31
|
## [1.4.5](https://github.com/proteinjs/user/compare/@proteinjs/user-server@1.4.3...@proteinjs/user-server@1.4.5) (2026-08-02)
|
|
7
32
|
|
|
8
33
|
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023 Brent Bahry
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -1,13 +1,10 @@
|
|
|
1
1
|
/** Load Dependency Source Graphs */
|
|
2
2
|
import '@proteinjs/db';
|
|
3
|
+
import '@proteinjs/db-file';
|
|
3
4
|
import '@proteinjs/email-server';
|
|
4
5
|
import '@proteinjs/logger';
|
|
5
|
-
import '@proteinjs/reflection';
|
|
6
6
|
import '@proteinjs/server';
|
|
7
7
|
import '@proteinjs/server-api';
|
|
8
8
|
import '@proteinjs/user';
|
|
9
|
-
import 'crypto-js';
|
|
10
|
-
import 'express-session';
|
|
11
|
-
import 'moment';
|
|
12
9
|
export * from '../index';
|
|
13
10
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../generated/index.ts"],"names":[],"mappings":"AAAA,oCAAoC;AAEpC,OAAO,eAAe,CAAC;AACvB,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../generated/index.ts"],"names":[],"mappings":"AAAA,oCAAoC;AAEpC,OAAO,eAAe,CAAC;AACvB,OAAO,oBAAoB,CAAC;AAC5B,OAAO,yBAAyB,CAAC;AACjC,OAAO,mBAAmB,CAAC;AAC3B,OAAO,mBAAmB,CAAC;AAC3B,OAAO,uBAAuB,CAAC;AAC/B,OAAO,iBAAiB,CAAC;AAmDzB,cAAc,UAAU,CAAC"}
|
package/dist/generated/index.js
CHANGED
|
@@ -16,21 +16,20 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
16
16
|
};
|
|
17
17
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
18
|
require("@proteinjs/db");
|
|
19
|
+
require("@proteinjs/db-file");
|
|
19
20
|
require("@proteinjs/email-server");
|
|
20
21
|
require("@proteinjs/logger");
|
|
21
|
-
require("@proteinjs/reflection");
|
|
22
22
|
require("@proteinjs/server");
|
|
23
23
|
require("@proteinjs/server-api");
|
|
24
24
|
require("@proteinjs/user");
|
|
25
|
-
require("crypto-js");
|
|
26
|
-
require("express-session");
|
|
27
|
-
require("moment");
|
|
28
25
|
/** Generate Source Graph */
|
|
29
|
-
var sourceGraph = "{\"options\":{\"directed\":true,\"multigraph\":false,\"compound\":false},\"nodes\":[{\"v\":\"@proteinjs/user-server/DbSessionStore\",\"value\":{\"packageName\":\"@proteinjs/user-server\",\"name\":\"DbSessionStore\",\"filePath\":\"/Users/brentbahry/repos/farm/n3xa2/packages/proteinjs/packages/user/packages/server/src/authentication/DbSessionStore.ts\",\"qualifiedName\":\"@proteinjs/user-server/DbSessionStore\",\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"properties\":[{\"name\":\"TWELVE_HOURS\",\"type\":null,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":true,\"visibility\":\"private\"},{\"name\":\"TOUCH_INTERVAL\",\"type\":null,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":true,\"visibility\":\"private\"},{\"name\":\"logger\",\"type\":null,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"private\"},{\"name\":\"lastTouchMs\",\"type\":null,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"private\"},{\"name\":\"get\",\"type\":null,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\"},{\"name\":\"set\",\"type\":null,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\"},{\"name\":\"touch\",\"type\":null,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\"},{\"name\":\"destroy\",\"type\":null,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\"}],\"methods\":[{\"name\":\"isTransactionAbort\",\"returnType\":{\"packageName\":\"\",\"name\":\"boolean\",\"filePath\":null,\"qualifiedName\":\"/boolean\",\"typeParameters\":null,\"directParents\":null},\"isAsync\":false,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":true,\"visibility\":\"private\",\"parameters\":[{\"name\":\"error\",\"type\":{\"packageName\":\"\",\"name\":\"any\",\"filePath\":null,\"qualifiedName\":\"/any\",\"typeParameters\":null,\"directParents\":null}}]},{\"name\":\"insertOrUpdate\",\"returnType\":{\"packageName\":\"\",\"name\":\"Promise<void>\",\"filePath\":null,\"qualifiedName\":\"/Promise<void>\",\"typeParameters\":null,\"directParents\":null},\"isAsync\":true,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"private\",\"parameters\":[{\"name\":\"sessionId\",\"type\":{\"packageName\":\"\",\"name\":\"string\",\"filePath\":null,\"qualifiedName\":\"/string\",\"typeParameters\":null,\"directParents\":null}},{\"name\":\"session\",\"type\":{\"packageName\":\"\",\"name\":\"Express.SessionData\",\"filePath\":null,\"qualifiedName\":\"/Express.SessionData\",\"typeParameters\":null,\"directParents\":null}},{\"name\":\"cb\",\"type\":{\"packageName\":\"\",\"name\":\"(error?: any) => void\",\"filePath\":null,\"qualifiedName\":\"/(error?: any) => void\",\"typeParameters\":null,\"directParents\":null}}]},{\"name\":\"sweep\",\"returnType\":{\"packageName\":\"\",\"name\":\"Promise<void>\",\"filePath\":null,\"qualifiedName\":\"/Promise<void>\",\"typeParameters\":null,\"directParents\":null},\"isAsync\":true,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"private\",\"parameters\":[]}],\"typeParameters\":[],\"directParentInterfaces\":[],\"directParentClasses\":[{\"packageName\":\"express-session\",\"name\":\"Store\",\"filePath\":null,\"qualifiedName\":\"express-session/Store\",\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"properties\":[],\"methods\":[],\"typeParameters\":[],\"directParentInterfaces\":[],\"directParentClasses\":[]}],\"sourceType\":2}},{\"v\":\"express-session/Store\"},{\"v\":\"@proteinjs/user-server/SocketIOSessionWatcher\",\"value\":{\"packageName\":\"@proteinjs/user-server\",\"name\":\"SocketIOSessionWatcher\",\"filePath\":\"/Users/brentbahry/repos/farm/n3xa2/packages/proteinjs/packages/user/packages/server/src/authentication/SocketIOSessionWatcher.ts\",\"qualifiedName\":\"@proteinjs/user-server/SocketIOSessionWatcher\",\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"properties\":[],\"methods\":[{\"name\":\"name\",\"returnType\":{\"packageName\":\"\",\"name\":\"string\",\"filePath\":null,\"qualifiedName\":\"/string\",\"typeParameters\":null,\"directParents\":null},\"isAsync\":false,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"parameters\":[]},{\"name\":\"table\",\"returnType\":{\"packageName\":\"\",\"name\":\"Table<Session>\",\"filePath\":null,\"qualifiedName\":\"/Table<Session>\",\"typeParameters\":null,\"directParents\":null},\"isAsync\":false,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"parameters\":[]},{\"name\":\"afterDelete\",\"returnType\":{\"packageName\":\"\",\"name\":\"Promise<void>\",\"filePath\":null,\"qualifiedName\":\"/Promise<void>\",\"typeParameters\":null,\"directParents\":null},\"isAsync\":true,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"parameters\":[{\"name\":\"recordDeleteCount\",\"type\":{\"packageName\":\"\",\"name\":\"number\",\"filePath\":null,\"qualifiedName\":\"/number\",\"typeParameters\":null,\"directParents\":null}},{\"name\":\"deletedRecords\",\"type\":{\"packageName\":\"\",\"name\":\"T[]\",\"filePath\":null,\"qualifiedName\":\"/T[]\",\"typeParameters\":null,\"directParents\":null}},{\"name\":\"initialQb\",\"type\":{\"packageName\":\"\",\"name\":\"QueryBuilder<T>\",\"filePath\":null,\"qualifiedName\":\"/QueryBuilder<T>\",\"typeParameters\":null,\"directParents\":null}},{\"name\":\"deleteQb\",\"type\":{\"packageName\":\"\",\"name\":\"QueryBuilder<T>\",\"filePath\":null,\"qualifiedName\":\"/QueryBuilder<T>\",\"typeParameters\":null,\"directParents\":null}}]}],\"typeParameters\":[],\"directParentInterfaces\":[{\"packageName\":\"@proteinjs/db\",\"name\":\"TableWatcher\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/db/TableWatcher\",\"properties\":[],\"methods\":[],\"typeParameters\":[\"@proteinjs/user/Session\"],\"directParents\":[]}],\"directParentClasses\":[],\"sourceType\":2}},{\"v\":\"@proteinjs/db/TableWatcher\"},{\"v\":\"@proteinjs/user-server/userCache\",\"value\":{\"packageName\":\"@proteinjs/user-server\",\"name\":\"userCache\",\"filePath\":\"/Users/brentbahry/repos/farm/n3xa2/packages/proteinjs/packages/user/packages/server/src/authorization/userCache.ts\",\"qualifiedName\":\"@proteinjs/user-server/userCache\",\"type\":{\"packageName\":\"\",\"name\":\"SessionDataCache<User>\",\"filePath\":null,\"qualifiedName\":\"/SessionDataCache<User>\",\"typeParameters\":[],\"directParents\":[{\"packageName\":\"@proteinjs/server-api\",\"name\":\"SessionDataCache\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/server-api/SessionDataCache\",\"typeParameters\":[\"@proteinjs/user/User\"],\"directParents\":null}]},\"isExported\":true,\"isConst\":true,\"sourceType\":0}},{\"v\":\"@proteinjs/server-api/SessionDataCache\"},{\"v\":\"@proteinjs/user-server/devLogin\",\"value\":{\"packageName\":\"@proteinjs/user-server\",\"name\":\"devLogin\",\"filePath\":\"/Users/brentbahry/repos/farm/n3xa2/packages/proteinjs/packages/user/packages/server/src/routes/devLogin.ts\",\"qualifiedName\":\"@proteinjs/user-server/devLogin\",\"type\":{\"packageName\":\"@proteinjs/server-api\",\"name\":\"Route\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/server-api/Route\",\"typeParameters\":[],\"directParents\":[{\"packageName\":\"@proteinjs/server-api\",\"name\":\"Route\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/server-api/Route\",\"typeParameters\":[],\"directParents\":null}]},\"isExported\":true,\"isConst\":true,\"sourceType\":0}},{\"v\":\"@proteinjs/server-api/Route\"},{\"v\":\"@proteinjs/user-server/executePasswordReset\",\"value\":{\"packageName\":\"@proteinjs/user-server\",\"name\":\"executePasswordReset\",\"filePath\":\"/Users/brentbahry/repos/farm/n3xa2/packages/proteinjs/packages/user/packages/server/src/routes/executePasswordReset.ts\",\"qualifiedName\":\"@proteinjs/user-server/executePasswordReset\",\"type\":{\"packageName\":\"@proteinjs/server-api\",\"name\":\"Route\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/server-api/Route\",\"typeParameters\":[],\"directParents\":[{\"packageName\":\"@proteinjs/server-api\",\"name\":\"Route\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/server-api/Route\",\"typeParameters\":[],\"directParents\":null}]},\"isExported\":true,\"isConst\":true,\"sourceType\":0}},{\"v\":\"@proteinjs/user-server/initiatePasswordReset\",\"value\":{\"packageName\":\"@proteinjs/user-server\",\"name\":\"initiatePasswordReset\",\"filePath\":\"/Users/brentbahry/repos/farm/n3xa2/packages/proteinjs/packages/user/packages/server/src/routes/initiatePasswordReset.ts\",\"qualifiedName\":\"@proteinjs/user-server/initiatePasswordReset\",\"type\":{\"packageName\":\"@proteinjs/server-api\",\"name\":\"Route\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/server-api/Route\",\"typeParameters\":[],\"directParents\":[{\"packageName\":\"@proteinjs/server-api\",\"name\":\"Route\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/server-api/Route\",\"typeParameters\":[],\"directParents\":null}]},\"isExported\":true,\"isConst\":true,\"sourceType\":0}},{\"v\":\"@proteinjs/user-server/login\",\"value\":{\"packageName\":\"@proteinjs/user-server\",\"name\":\"login\",\"filePath\":\"/Users/brentbahry/repos/farm/n3xa2/packages/proteinjs/packages/user/packages/server/src/routes/login.ts\",\"qualifiedName\":\"@proteinjs/user-server/login\",\"type\":{\"packageName\":\"@proteinjs/server-api\",\"name\":\"Route\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/server-api/Route\",\"typeParameters\":[],\"directParents\":[{\"packageName\":\"@proteinjs/server-api\",\"name\":\"Route\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/server-api/Route\",\"typeParameters\":[],\"directParents\":null}]},\"isExported\":true,\"isConst\":true,\"sourceType\":0}},{\"v\":\"@proteinjs/user-server/logout\",\"value\":{\"packageName\":\"@proteinjs/user-server\",\"name\":\"logout\",\"filePath\":\"/Users/brentbahry/repos/farm/n3xa2/packages/proteinjs/packages/user/packages/server/src/routes/logout.ts\",\"qualifiedName\":\"@proteinjs/user-server/logout\",\"type\":{\"packageName\":\"@proteinjs/server-api\",\"name\":\"Route\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/server-api/Route\",\"typeParameters\":[],\"directParents\":[{\"packageName\":\"@proteinjs/server-api\",\"name\":\"Route\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/server-api/Route\",\"typeParameters\":[],\"directParents\":null}]},\"isExported\":true,\"isConst\":true,\"sourceType\":0}},{\"v\":\"@proteinjs/user-server/validateResetPasswordToken\",\"value\":{\"packageName\":\"@proteinjs/user-server\",\"name\":\"validateResetPasswordToken\",\"filePath\":\"/Users/brentbahry/repos/farm/n3xa2/packages/proteinjs/packages/user/packages/server/src/routes/validateResetPasswordToken.ts\",\"qualifiedName\":\"@proteinjs/user-server/validateResetPasswordToken\",\"type\":{\"packageName\":\"@proteinjs/server-api\",\"name\":\"Route\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/server-api/Route\",\"typeParameters\":[],\"directParents\":[{\"packageName\":\"@proteinjs/server-api\",\"name\":\"Route\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/server-api/Route\",\"typeParameters\":[],\"directParents\":null}]},\"isExported\":true,\"isConst\":true,\"sourceType\":0}},{\"v\":\"@proteinjs/user-server/AccessInvite\",\"value\":{\"packageName\":\"@proteinjs/user-server\",\"name\":\"AccessInvite\",\"filePath\":\"/Users/brentbahry/repos/farm/n3xa2/packages/proteinjs/packages/user/packages/server/src/services/AccessInvite.ts\",\"qualifiedName\":\"@proteinjs/user-server/AccessInvite\",\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"properties\":[{\"name\":\"serviceMetadata\",\"type\":null,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\"}],\"methods\":[{\"name\":\"createAccessInvite\",\"returnType\":{\"packageName\":\"\",\"name\":\"Promise<CreateAccessInviteResponse>\",\"filePath\":null,\"qualifiedName\":\"/Promise<CreateAccessInviteResponse>\",\"typeParameters\":null,\"directParents\":null},\"isAsync\":true,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"parameters\":[{\"name\":\"params\",\"type\":{\"packageName\":\"@proteinjs/user\",\"name\":\"CreateAccessInviteParams\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/user/CreateAccessInviteParams\",\"typeParameters\":null,\"directParents\":null}}]},{\"name\":\"acceptAccessInvite\",\"returnType\":{\"packageName\":\"\",\"name\":\"Promise<T | undefined>\",\"filePath\":null,\"qualifiedName\":\"/Promise<T | undefined>\",\"typeParameters\":null,\"directParents\":null},\"isAsync\":true,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"parameters\":[{\"name\":\"token\",\"type\":{\"packageName\":\"\",\"name\":\"string\",\"filePath\":null,\"qualifiedName\":\"/string\",\"typeParameters\":null,\"directParents\":null}}]}],\"typeParameters\":[\"/T extends Record\"],\"directParentInterfaces\":[{\"packageName\":\"@proteinjs/user\",\"name\":\"AccessInviteService\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/user/AccessInviteService\",\"properties\":[],\"methods\":[],\"typeParameters\":[\"/T\"],\"directParents\":[]}],\"directParentClasses\":[],\"sourceType\":2}},{\"v\":\"@proteinjs/user/AccessInviteService\"},{\"v\":\"@proteinjs/user-server/Roles\",\"value\":{\"packageName\":\"@proteinjs/user-server\",\"name\":\"Roles\",\"filePath\":\"/Users/brentbahry/repos/farm/n3xa2/packages/proteinjs/packages/user/packages/server/src/services/Roles.ts\",\"qualifiedName\":\"@proteinjs/user-server/Roles\",\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"properties\":[{\"name\":\"serviceMetadata\",\"type\":{\"packageName\":\"\",\"name\":\"Service['serviceMetadata']\",\"filePath\":null,\"qualifiedName\":\"/Service['serviceMetadata']\",\"typeParameters\":null,\"directParents\":null},\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\"}],\"methods\":[{\"name\":\"grantRole\",\"returnType\":{\"packageName\":\"\",\"name\":\"Promise<void>\",\"filePath\":null,\"qualifiedName\":\"/Promise<void>\",\"typeParameters\":null,\"directParents\":null},\"isAsync\":true,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"parameters\":[{\"name\":\"userId\",\"type\":{\"packageName\":\"\",\"name\":\"string\",\"filePath\":null,\"qualifiedName\":\"/string\",\"typeParameters\":null,\"directParents\":null}},{\"name\":\"role\",\"type\":{\"packageName\":\"\",\"name\":\"string\",\"filePath\":null,\"qualifiedName\":\"/string\",\"typeParameters\":null,\"directParents\":null}}]},{\"name\":\"revokeRole\",\"returnType\":{\"packageName\":\"\",\"name\":\"Promise<void>\",\"filePath\":null,\"qualifiedName\":\"/Promise<void>\",\"typeParameters\":null,\"directParents\":null},\"isAsync\":true,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"parameters\":[{\"name\":\"userId\",\"type\":{\"packageName\":\"\",\"name\":\"string\",\"filePath\":null,\"qualifiedName\":\"/string\",\"typeParameters\":null,\"directParents\":null}},{\"name\":\"role\",\"type\":{\"packageName\":\"\",\"name\":\"string\",\"filePath\":null,\"qualifiedName\":\"/string\",\"typeParameters\":null,\"directParents\":null}}]},{\"name\":\"changeRole\",\"returnType\":{\"packageName\":\"\",\"name\":\"Promise<void>\",\"filePath\":null,\"qualifiedName\":\"/Promise<void>\",\"typeParameters\":null,\"directParents\":null},\"isAsync\":true,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"private\",\"parameters\":[{\"name\":\"userId\",\"type\":{\"packageName\":\"\",\"name\":\"string\",\"filePath\":null,\"qualifiedName\":\"/string\",\"typeParameters\":null,\"directParents\":null}},{\"name\":\"role\",\"type\":{\"packageName\":\"\",\"name\":\"string\",\"filePath\":null,\"qualifiedName\":\"/string\",\"typeParameters\":null,\"directParents\":null}},{\"name\":\"action\",\"type\":{\"packageName\":\"\",\"name\":\"'grant' | 'revoke'\",\"filePath\":null,\"qualifiedName\":\"/'grant' | 'revoke'\",\"typeParameters\":null,\"directParents\":null}}]}],\"typeParameters\":[],\"directParentInterfaces\":[{\"packageName\":\"@proteinjs/user\",\"name\":\"RolesService\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/user/RolesService\",\"properties\":[],\"methods\":[],\"typeParameters\":[],\"directParents\":[]}],\"directParentClasses\":[],\"sourceType\":2}},{\"v\":\"@proteinjs/user/RolesService\"},{\"v\":\"@proteinjs/user-server/DefaultInviteConfigFactory\",\"value\":{\"packageName\":\"@proteinjs/user-server\",\"name\":\"DefaultInviteConfigFactory\",\"filePath\":\"/Users/brentbahry/repos/farm/n3xa2/packages/proteinjs/packages/user/packages/server/src/services/Signup.ts\",\"qualifiedName\":\"@proteinjs/user-server/DefaultInviteConfigFactory\",\"properties\":[],\"methods\":[{\"name\":\"getConfig\",\"returnType\":{\"packageName\":\"@proteinjs/user-server\",\"name\":\"InviteConfig\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/user-server/InviteConfig\",\"typeParameters\":null,\"directParents\":null},\"isAsync\":false,\"isOptional\":false,\"isAbstract\":true,\"isStatic\":false,\"visibility\":\"public\",\"parameters\":[]}],\"typeParameters\":[],\"directParents\":[{\"packageName\":\"@proteinjs/reflection\",\"name\":\"Loadable\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/reflection/Loadable\",\"properties\":[],\"methods\":[],\"typeParameters\":[],\"directParents\":[]}],\"sourceType\":3}},{\"v\":\"@proteinjs/reflection/Loadable\"},{\"v\":\"@proteinjs/user-server/Signup\",\"value\":{\"packageName\":\"@proteinjs/user-server\",\"name\":\"Signup\",\"filePath\":\"/Users/brentbahry/repos/farm/n3xa2/packages/proteinjs/packages/user/packages/server/src/services/Signup.ts\",\"qualifiedName\":\"@proteinjs/user-server/Signup\",\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"properties\":[{\"name\":\"serviceMetadata\",\"type\":null,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\"}],\"methods\":[{\"name\":\"createUser\",\"returnType\":{\"packageName\":\"\",\"name\":\"Promise<void>\",\"filePath\":null,\"qualifiedName\":\"/Promise<void>\",\"typeParameters\":null,\"directParents\":null},\"isAsync\":true,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"parameters\":[{\"name\":\"user\",\"type\":{\"packageName\":\"@proteinjs/user\",\"name\":\"UserSignup\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/user/UserSignup\",\"typeParameters\":null,\"directParents\":null}},{\"name\":\"token\",\"type\":{\"packageName\":\"\",\"name\":\"string\",\"filePath\":null,\"qualifiedName\":\"/string\",\"typeParameters\":null,\"directParents\":null}}]},{\"name\":\"sendInvite\",\"returnType\":{\"packageName\":\"\",\"name\":\"Promise<SendInviteResponse>\",\"filePath\":null,\"qualifiedName\":\"/Promise<SendInviteResponse>\",\"typeParameters\":null,\"directParents\":null},\"isAsync\":true,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"parameters\":[{\"name\":\"email\",\"type\":{\"packageName\":\"\",\"name\":\"string\",\"filePath\":null,\"qualifiedName\":\"/string\",\"typeParameters\":null,\"directParents\":null}}]},{\"name\":\"revokeInvite\",\"returnType\":{\"packageName\":\"\",\"name\":\"Promise<void>\",\"filePath\":null,\"qualifiedName\":\"/Promise<void>\",\"typeParameters\":null,\"directParents\":null},\"isAsync\":true,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"parameters\":[{\"name\":\"email\",\"type\":{\"packageName\":\"\",\"name\":\"string\",\"filePath\":null,\"qualifiedName\":\"/string\",\"typeParameters\":null,\"directParents\":null}}]},{\"name\":\"initializeSignup\",\"returnType\":{\"packageName\":\"\",\"name\":\"Promise<InitializeSignupResponse>\",\"filePath\":null,\"qualifiedName\":\"/Promise<InitializeSignupResponse>\",\"typeParameters\":null,\"directParents\":null},\"isAsync\":true,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"parameters\":[{\"name\":\"inviteToken\",\"type\":{\"packageName\":\"\",\"name\":\"string | undefined\",\"filePath\":null,\"qualifiedName\":\"/string | undefined\",\"typeParameters\":null,\"directParents\":null}}]},{\"name\":\"lookupInvite\",\"returnType\":{\"packageName\":\"\",\"name\":\"Promise<InviteLookup>\",\"filePath\":null,\"qualifiedName\":\"/Promise<InviteLookup>\",\"typeParameters\":null,\"directParents\":null},\"isAsync\":true,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"private\",\"parameters\":[{\"name\":\"token\",\"type\":{\"packageName\":\"\",\"name\":\"string\",\"filePath\":null,\"qualifiedName\":\"/string\",\"typeParameters\":null,\"directParents\":null}}]}],\"typeParameters\":[],\"directParentInterfaces\":[{\"packageName\":\"@proteinjs/user\",\"name\":\"SignupService\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/user/SignupService\",\"properties\":[],\"methods\":[],\"typeParameters\":[],\"directParents\":[]}],\"directParentClasses\":[],\"sourceType\":2}},{\"v\":\"@proteinjs/user/SignupService\"},{\"v\":\"@proteinjs/user-server/UpdateUserInfo\",\"value\":{\"packageName\":\"@proteinjs/user-server\",\"name\":\"UpdateUserInfo\",\"filePath\":\"/Users/brentbahry/repos/farm/n3xa2/packages/proteinjs/packages/user/packages/server/src/services/UpdateUserInfo.ts\",\"qualifiedName\":\"@proteinjs/user-server/UpdateUserInfo\",\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"properties\":[{\"name\":\"serviceMetadata\",\"type\":null,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\"}],\"methods\":[{\"name\":\"updateName\",\"returnType\":{\"packageName\":\"\",\"name\":\"Promise<void>\",\"filePath\":null,\"qualifiedName\":\"/Promise<void>\",\"typeParameters\":null,\"directParents\":null},\"isAsync\":true,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"parameters\":[{\"name\":\"name\",\"type\":{\"packageName\":\"\",\"name\":\"string\",\"filePath\":null,\"qualifiedName\":\"/string\",\"typeParameters\":null,\"directParents\":null}}]},{\"name\":\"updatePassword\",\"returnType\":{\"packageName\":\"\",\"name\":\"Promise<UpdatePasswordResponse>\",\"filePath\":null,\"qualifiedName\":\"/Promise<UpdatePasswordResponse>\",\"typeParameters\":null,\"directParents\":null},\"isAsync\":true,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"parameters\":[{\"name\":\"currentPassword\",\"type\":{\"packageName\":\"\",\"name\":\"string\",\"filePath\":null,\"qualifiedName\":\"/string\",\"typeParameters\":null,\"directParents\":null}},{\"name\":\"newPassword\",\"type\":{\"packageName\":\"\",\"name\":\"string\",\"filePath\":null,\"qualifiedName\":\"/string\",\"typeParameters\":null,\"directParents\":null}}]}],\"typeParameters\":[],\"directParentInterfaces\":[{\"packageName\":\"@proteinjs/user\",\"name\":\"UpdateUserInfoService\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/user/UpdateUserInfoService\",\"properties\":[],\"methods\":[],\"typeParameters\":[],\"directParents\":[]}],\"directParentClasses\":[],\"sourceType\":2}},{\"v\":\"@proteinjs/user/UpdateUserInfoService\"},{\"v\":\"@proteinjs/user-server/BackfillUserRolesArray\",\"value\":{\"packageName\":\"@proteinjs/user-server\",\"name\":\"BackfillUserRolesArray\",\"filePath\":\"/Users/brentbahry/repos/farm/n3xa2/packages/proteinjs/packages/user/packages/server/src/migrations/BackfillUserRolesArray.ts\",\"qualifiedName\":\"@proteinjs/user-server/BackfillUserRolesArray\",\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"properties\":[{\"name\":\"table\",\"type\":null,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\"},{\"name\":\"record\",\"type\":null,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\"}],\"methods\":[],\"typeParameters\":[],\"directParentInterfaces\":[{\"packageName\":\"@proteinjs/db\",\"name\":\"SourceRecordLoader\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/db/SourceRecordLoader\",\"properties\":[],\"methods\":[],\"typeParameters\":[\"@proteinjs/db/Migration\"],\"directParents\":[]}],\"directParentClasses\":[],\"sourceType\":2}},{\"v\":\"@proteinjs/db/SourceRecordLoader\"}],\"edges\":[{\"v\":\"@proteinjs/user-server/DbSessionStore\",\"w\":\"express-session/Store\",\"value\":\"extends class\"},{\"v\":\"@proteinjs/user-server/SocketIOSessionWatcher\",\"w\":\"@proteinjs/db/TableWatcher\",\"value\":\"implements interface\"},{\"v\":\"@proteinjs/user-server/userCache\",\"w\":\"@proteinjs/server-api/SessionDataCache\",\"value\":\"has type\"},{\"v\":\"@proteinjs/user-server/devLogin\",\"w\":\"@proteinjs/server-api/Route\",\"value\":\"has type\"},{\"v\":\"@proteinjs/user-server/executePasswordReset\",\"w\":\"@proteinjs/server-api/Route\",\"value\":\"has type\"},{\"v\":\"@proteinjs/user-server/initiatePasswordReset\",\"w\":\"@proteinjs/server-api/Route\",\"value\":\"has type\"},{\"v\":\"@proteinjs/user-server/login\",\"w\":\"@proteinjs/server-api/Route\",\"value\":\"has type\"},{\"v\":\"@proteinjs/user-server/logout\",\"w\":\"@proteinjs/server-api/Route\",\"value\":\"has type\"},{\"v\":\"@proteinjs/user-server/validateResetPasswordToken\",\"w\":\"@proteinjs/server-api/Route\",\"value\":\"has type\"},{\"v\":\"@proteinjs/user-server/AccessInvite\",\"w\":\"@proteinjs/user/AccessInviteService\",\"value\":\"implements interface\"},{\"v\":\"@proteinjs/user-server/Roles\",\"w\":\"@proteinjs/user/RolesService\",\"value\":\"implements interface\"},{\"v\":\"@proteinjs/user-server/DefaultInviteConfigFactory\",\"w\":\"@proteinjs/reflection/Loadable\",\"value\":\"extends interface\"},{\"v\":\"@proteinjs/user-server/Signup\",\"w\":\"@proteinjs/user/SignupService\",\"value\":\"implements interface\"},{\"v\":\"@proteinjs/user-server/UpdateUserInfo\",\"w\":\"@proteinjs/user/UpdateUserInfoService\",\"value\":\"implements interface\"},{\"v\":\"@proteinjs/user-server/BackfillUserRolesArray\",\"w\":\"@proteinjs/db/SourceRecordLoader\",\"value\":\"implements interface\"}]}";
|
|
26
|
+
var sourceGraph = "{\"options\":{\"directed\":true,\"multigraph\":false,\"compound\":false},\"nodes\":[{\"v\":\"@proteinjs/user-server/DbSessionStore\",\"value\":{\"packageName\":\"@proteinjs/user-server\",\"name\":\"DbSessionStore\",\"filePath\":\"/home/runner/work/user/user/packages/server/src/authentication/DbSessionStore.ts\",\"qualifiedName\":\"@proteinjs/user-server/DbSessionStore\",\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"properties\":[{\"name\":\"TWELVE_HOURS\",\"type\":null,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":true,\"visibility\":\"private\"},{\"name\":\"TOUCH_INTERVAL\",\"type\":null,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":true,\"visibility\":\"private\"},{\"name\":\"logger\",\"type\":null,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"private\"},{\"name\":\"lastTouchMs\",\"type\":null,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"private\"},{\"name\":\"get\",\"type\":null,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\"},{\"name\":\"set\",\"type\":null,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\"},{\"name\":\"touch\",\"type\":null,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\"},{\"name\":\"destroy\",\"type\":null,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\"}],\"methods\":[{\"name\":\"isTransactionAbort\",\"returnType\":{\"packageName\":\"\",\"name\":\"boolean\",\"filePath\":null,\"qualifiedName\":\"/boolean\",\"typeParameters\":null,\"directParents\":null},\"isAsync\":false,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":true,\"visibility\":\"private\",\"parameters\":[{\"name\":\"error\",\"type\":{\"packageName\":\"\",\"name\":\"any\",\"filePath\":null,\"qualifiedName\":\"/any\",\"typeParameters\":null,\"directParents\":null}}]},{\"name\":\"insertOrUpdate\",\"returnType\":{\"packageName\":\"\",\"name\":\"Promise<void>\",\"filePath\":null,\"qualifiedName\":\"/Promise<void>\",\"typeParameters\":null,\"directParents\":null},\"isAsync\":true,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"private\",\"parameters\":[{\"name\":\"sessionId\",\"type\":{\"packageName\":\"\",\"name\":\"string\",\"filePath\":null,\"qualifiedName\":\"/string\",\"typeParameters\":null,\"directParents\":null}},{\"name\":\"session\",\"type\":{\"packageName\":\"\",\"name\":\"Express.SessionData\",\"filePath\":null,\"qualifiedName\":\"/Express.SessionData\",\"typeParameters\":null,\"directParents\":null}},{\"name\":\"cb\",\"type\":{\"packageName\":\"\",\"name\":\"(error?: any) => void\",\"filePath\":null,\"qualifiedName\":\"/(error?: any) => void\",\"typeParameters\":null,\"directParents\":null}}]},{\"name\":\"sweep\",\"returnType\":{\"packageName\":\"\",\"name\":\"Promise<void>\",\"filePath\":null,\"qualifiedName\":\"/Promise<void>\",\"typeParameters\":null,\"directParents\":null},\"isAsync\":true,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"private\",\"parameters\":[]}],\"typeParameters\":[],\"directParentInterfaces\":[],\"directParentClasses\":[{\"packageName\":\"express-session\",\"name\":\"Store\",\"filePath\":null,\"qualifiedName\":\"express-session/Store\",\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"properties\":[],\"methods\":[],\"typeParameters\":[],\"directParentInterfaces\":[],\"directParentClasses\":[]}],\"sourceType\":2}},{\"v\":\"express-session/Store\"},{\"v\":\"@proteinjs/user-server/SocketIOSessionWatcher\",\"value\":{\"packageName\":\"@proteinjs/user-server\",\"name\":\"SocketIOSessionWatcher\",\"filePath\":\"/home/runner/work/user/user/packages/server/src/authentication/SocketIOSessionWatcher.ts\",\"qualifiedName\":\"@proteinjs/user-server/SocketIOSessionWatcher\",\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"properties\":[],\"methods\":[{\"name\":\"name\",\"returnType\":{\"packageName\":\"\",\"name\":\"string\",\"filePath\":null,\"qualifiedName\":\"/string\",\"typeParameters\":null,\"directParents\":null},\"isAsync\":false,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"parameters\":[]},{\"name\":\"table\",\"returnType\":{\"packageName\":\"\",\"name\":\"Table<Session>\",\"filePath\":null,\"qualifiedName\":\"/Table<Session>\",\"typeParameters\":null,\"directParents\":null},\"isAsync\":false,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"parameters\":[]},{\"name\":\"afterDelete\",\"returnType\":{\"packageName\":\"\",\"name\":\"Promise<void>\",\"filePath\":null,\"qualifiedName\":\"/Promise<void>\",\"typeParameters\":null,\"directParents\":null},\"isAsync\":true,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"parameters\":[{\"name\":\"recordDeleteCount\",\"type\":{\"packageName\":\"\",\"name\":\"number\",\"filePath\":null,\"qualifiedName\":\"/number\",\"typeParameters\":null,\"directParents\":null}},{\"name\":\"deletedRecords\",\"type\":{\"packageName\":\"\",\"name\":\"T[]\",\"filePath\":null,\"qualifiedName\":\"/T[]\",\"typeParameters\":null,\"directParents\":null}},{\"name\":\"initialQb\",\"type\":{\"packageName\":\"\",\"name\":\"QueryBuilder<T>\",\"filePath\":null,\"qualifiedName\":\"/QueryBuilder<T>\",\"typeParameters\":null,\"directParents\":null}},{\"name\":\"deleteQb\",\"type\":{\"packageName\":\"\",\"name\":\"QueryBuilder<T>\",\"filePath\":null,\"qualifiedName\":\"/QueryBuilder<T>\",\"typeParameters\":null,\"directParents\":null}}]}],\"typeParameters\":[],\"directParentInterfaces\":[{\"packageName\":\"@proteinjs/db\",\"name\":\"TableWatcher\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/db/TableWatcher\",\"properties\":[],\"methods\":[],\"typeParameters\":[\"@proteinjs/user/Session\"],\"directParents\":[]}],\"directParentClasses\":[],\"sourceType\":2}},{\"v\":\"@proteinjs/db/TableWatcher\"},{\"v\":\"@proteinjs/user-server/userCache\",\"value\":{\"packageName\":\"@proteinjs/user-server\",\"name\":\"userCache\",\"filePath\":\"/home/runner/work/user/user/packages/server/src/authorization/userCache.ts\",\"qualifiedName\":\"@proteinjs/user-server/userCache\",\"type\":{\"packageName\":\"\",\"name\":\"SessionDataCache<User>\",\"filePath\":null,\"qualifiedName\":\"/SessionDataCache<User>\",\"typeParameters\":[],\"directParents\":[{\"packageName\":\"@proteinjs/server-api\",\"name\":\"SessionDataCache\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/server-api/SessionDataCache\",\"typeParameters\":[\"@proteinjs/user/User\"],\"directParents\":null}]},\"isExported\":true,\"isConst\":true,\"sourceType\":0}},{\"v\":\"@proteinjs/server-api/SessionDataCache\"},{\"v\":\"@proteinjs/user-server/BackfillUserRolesArray\",\"value\":{\"packageName\":\"@proteinjs/user-server\",\"name\":\"BackfillUserRolesArray\",\"filePath\":\"/home/runner/work/user/user/packages/server/src/migrations/BackfillUserRolesArray.ts\",\"qualifiedName\":\"@proteinjs/user-server/BackfillUserRolesArray\",\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"properties\":[{\"name\":\"table\",\"type\":null,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\"},{\"name\":\"record\",\"type\":null,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\"}],\"methods\":[],\"typeParameters\":[],\"directParentInterfaces\":[{\"packageName\":\"@proteinjs/db\",\"name\":\"SourceRecordLoader\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/db/SourceRecordLoader\",\"properties\":[],\"methods\":[],\"typeParameters\":[\"@proteinjs/db/Migration\"],\"directParents\":[]}],\"directParentClasses\":[],\"sourceType\":2}},{\"v\":\"@proteinjs/db/SourceRecordLoader\"},{\"v\":\"@proteinjs/user-server/avatar\",\"value\":{\"packageName\":\"@proteinjs/user-server\",\"name\":\"avatar\",\"filePath\":\"/home/runner/work/user/user/packages/server/src/routes/avatar.ts\",\"qualifiedName\":\"@proteinjs/user-server/avatar\",\"type\":{\"packageName\":\"@proteinjs/server-api\",\"name\":\"Route\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/server-api/Route\",\"typeParameters\":[],\"directParents\":[{\"packageName\":\"@proteinjs/server-api\",\"name\":\"Route\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/server-api/Route\",\"typeParameters\":[],\"directParents\":null}]},\"isExported\":true,\"isConst\":true,\"sourceType\":0}},{\"v\":\"@proteinjs/server-api/Route\"},{\"v\":\"@proteinjs/user-server/devLogin\",\"value\":{\"packageName\":\"@proteinjs/user-server\",\"name\":\"devLogin\",\"filePath\":\"/home/runner/work/user/user/packages/server/src/routes/devLogin.ts\",\"qualifiedName\":\"@proteinjs/user-server/devLogin\",\"type\":{\"packageName\":\"@proteinjs/server-api\",\"name\":\"Route\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/server-api/Route\",\"typeParameters\":[],\"directParents\":[{\"packageName\":\"@proteinjs/server-api\",\"name\":\"Route\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/server-api/Route\",\"typeParameters\":[],\"directParents\":null}]},\"isExported\":true,\"isConst\":true,\"sourceType\":0}},{\"v\":\"@proteinjs/user-server/executePasswordReset\",\"value\":{\"packageName\":\"@proteinjs/user-server\",\"name\":\"executePasswordReset\",\"filePath\":\"/home/runner/work/user/user/packages/server/src/routes/executePasswordReset.ts\",\"qualifiedName\":\"@proteinjs/user-server/executePasswordReset\",\"type\":{\"packageName\":\"@proteinjs/server-api\",\"name\":\"Route\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/server-api/Route\",\"typeParameters\":[],\"directParents\":[{\"packageName\":\"@proteinjs/server-api\",\"name\":\"Route\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/server-api/Route\",\"typeParameters\":[],\"directParents\":null}]},\"isExported\":true,\"isConst\":true,\"sourceType\":0}},{\"v\":\"@proteinjs/user-server/initiatePasswordReset\",\"value\":{\"packageName\":\"@proteinjs/user-server\",\"name\":\"initiatePasswordReset\",\"filePath\":\"/home/runner/work/user/user/packages/server/src/routes/initiatePasswordReset.ts\",\"qualifiedName\":\"@proteinjs/user-server/initiatePasswordReset\",\"type\":{\"packageName\":\"@proteinjs/server-api\",\"name\":\"Route\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/server-api/Route\",\"typeParameters\":[],\"directParents\":[{\"packageName\":\"@proteinjs/server-api\",\"name\":\"Route\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/server-api/Route\",\"typeParameters\":[],\"directParents\":null}]},\"isExported\":true,\"isConst\":true,\"sourceType\":0}},{\"v\":\"@proteinjs/user-server/login\",\"value\":{\"packageName\":\"@proteinjs/user-server\",\"name\":\"login\",\"filePath\":\"/home/runner/work/user/user/packages/server/src/routes/login.ts\",\"qualifiedName\":\"@proteinjs/user-server/login\",\"type\":{\"packageName\":\"@proteinjs/server-api\",\"name\":\"Route\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/server-api/Route\",\"typeParameters\":[],\"directParents\":[{\"packageName\":\"@proteinjs/server-api\",\"name\":\"Route\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/server-api/Route\",\"typeParameters\":[],\"directParents\":null}]},\"isExported\":true,\"isConst\":true,\"sourceType\":0}},{\"v\":\"@proteinjs/user-server/logout\",\"value\":{\"packageName\":\"@proteinjs/user-server\",\"name\":\"logout\",\"filePath\":\"/home/runner/work/user/user/packages/server/src/routes/logout.ts\",\"qualifiedName\":\"@proteinjs/user-server/logout\",\"type\":{\"packageName\":\"@proteinjs/server-api\",\"name\":\"Route\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/server-api/Route\",\"typeParameters\":[],\"directParents\":[{\"packageName\":\"@proteinjs/server-api\",\"name\":\"Route\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/server-api/Route\",\"typeParameters\":[],\"directParents\":null}]},\"isExported\":true,\"isConst\":true,\"sourceType\":0}},{\"v\":\"@proteinjs/user-server/validateResetPasswordToken\",\"value\":{\"packageName\":\"@proteinjs/user-server\",\"name\":\"validateResetPasswordToken\",\"filePath\":\"/home/runner/work/user/user/packages/server/src/routes/validateResetPasswordToken.ts\",\"qualifiedName\":\"@proteinjs/user-server/validateResetPasswordToken\",\"type\":{\"packageName\":\"@proteinjs/server-api\",\"name\":\"Route\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/server-api/Route\",\"typeParameters\":[],\"directParents\":[{\"packageName\":\"@proteinjs/server-api\",\"name\":\"Route\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/server-api/Route\",\"typeParameters\":[],\"directParents\":null}]},\"isExported\":true,\"isConst\":true,\"sourceType\":0}},{\"v\":\"@proteinjs/user-server/AccessInvite\",\"value\":{\"packageName\":\"@proteinjs/user-server\",\"name\":\"AccessInvite\",\"filePath\":\"/home/runner/work/user/user/packages/server/src/services/AccessInvite.ts\",\"qualifiedName\":\"@proteinjs/user-server/AccessInvite\",\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"properties\":[{\"name\":\"serviceMetadata\",\"type\":null,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\"}],\"methods\":[{\"name\":\"createAccessInvite\",\"returnType\":{\"packageName\":\"\",\"name\":\"Promise<CreateAccessInviteResponse>\",\"filePath\":null,\"qualifiedName\":\"/Promise<CreateAccessInviteResponse>\",\"typeParameters\":null,\"directParents\":null},\"isAsync\":true,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"parameters\":[{\"name\":\"params\",\"type\":{\"packageName\":\"@proteinjs/user\",\"name\":\"CreateAccessInviteParams\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/user/CreateAccessInviteParams\",\"typeParameters\":null,\"directParents\":null}}]},{\"name\":\"acceptAccessInvite\",\"returnType\":{\"packageName\":\"\",\"name\":\"Promise<T | undefined>\",\"filePath\":null,\"qualifiedName\":\"/Promise<T | undefined>\",\"typeParameters\":null,\"directParents\":null},\"isAsync\":true,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"parameters\":[{\"name\":\"token\",\"type\":{\"packageName\":\"\",\"name\":\"string\",\"filePath\":null,\"qualifiedName\":\"/string\",\"typeParameters\":null,\"directParents\":null}}]}],\"typeParameters\":[\"/T extends Record\"],\"directParentInterfaces\":[{\"packageName\":\"@proteinjs/user\",\"name\":\"AccessInviteService\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/user/AccessInviteService\",\"properties\":[],\"methods\":[],\"typeParameters\":[\"/T\"],\"directParents\":[]}],\"directParentClasses\":[],\"sourceType\":2}},{\"v\":\"@proteinjs/user/AccessInviteService\"},{\"v\":\"@proteinjs/user-server/Roles\",\"value\":{\"packageName\":\"@proteinjs/user-server\",\"name\":\"Roles\",\"filePath\":\"/home/runner/work/user/user/packages/server/src/services/Roles.ts\",\"qualifiedName\":\"@proteinjs/user-server/Roles\",\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"properties\":[{\"name\":\"serviceMetadata\",\"type\":{\"packageName\":\"\",\"name\":\"Service['serviceMetadata']\",\"filePath\":null,\"qualifiedName\":\"/Service['serviceMetadata']\",\"typeParameters\":null,\"directParents\":null},\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\"}],\"methods\":[{\"name\":\"grantRole\",\"returnType\":{\"packageName\":\"\",\"name\":\"Promise<void>\",\"filePath\":null,\"qualifiedName\":\"/Promise<void>\",\"typeParameters\":null,\"directParents\":null},\"isAsync\":true,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"parameters\":[{\"name\":\"userId\",\"type\":{\"packageName\":\"\",\"name\":\"string\",\"filePath\":null,\"qualifiedName\":\"/string\",\"typeParameters\":null,\"directParents\":null}},{\"name\":\"role\",\"type\":{\"packageName\":\"\",\"name\":\"string\",\"filePath\":null,\"qualifiedName\":\"/string\",\"typeParameters\":null,\"directParents\":null}}]},{\"name\":\"revokeRole\",\"returnType\":{\"packageName\":\"\",\"name\":\"Promise<void>\",\"filePath\":null,\"qualifiedName\":\"/Promise<void>\",\"typeParameters\":null,\"directParents\":null},\"isAsync\":true,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"parameters\":[{\"name\":\"userId\",\"type\":{\"packageName\":\"\",\"name\":\"string\",\"filePath\":null,\"qualifiedName\":\"/string\",\"typeParameters\":null,\"directParents\":null}},{\"name\":\"role\",\"type\":{\"packageName\":\"\",\"name\":\"string\",\"filePath\":null,\"qualifiedName\":\"/string\",\"typeParameters\":null,\"directParents\":null}}]},{\"name\":\"changeRole\",\"returnType\":{\"packageName\":\"\",\"name\":\"Promise<void>\",\"filePath\":null,\"qualifiedName\":\"/Promise<void>\",\"typeParameters\":null,\"directParents\":null},\"isAsync\":true,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"private\",\"parameters\":[{\"name\":\"userId\",\"type\":{\"packageName\":\"\",\"name\":\"string\",\"filePath\":null,\"qualifiedName\":\"/string\",\"typeParameters\":null,\"directParents\":null}},{\"name\":\"role\",\"type\":{\"packageName\":\"\",\"name\":\"string\",\"filePath\":null,\"qualifiedName\":\"/string\",\"typeParameters\":null,\"directParents\":null}},{\"name\":\"action\",\"type\":{\"packageName\":\"\",\"name\":\"'grant' | 'revoke'\",\"filePath\":null,\"qualifiedName\":\"/'grant' | 'revoke'\",\"typeParameters\":null,\"directParents\":null}}]}],\"typeParameters\":[],\"directParentInterfaces\":[{\"packageName\":\"@proteinjs/user\",\"name\":\"RolesService\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/user/RolesService\",\"properties\":[],\"methods\":[],\"typeParameters\":[],\"directParents\":[]}],\"directParentClasses\":[],\"sourceType\":2}},{\"v\":\"@proteinjs/user/RolesService\"},{\"v\":\"@proteinjs/user-server/DefaultInviteConfigFactory\",\"value\":{\"packageName\":\"@proteinjs/user-server\",\"name\":\"DefaultInviteConfigFactory\",\"filePath\":\"/home/runner/work/user/user/packages/server/src/services/Signup.ts\",\"qualifiedName\":\"@proteinjs/user-server/DefaultInviteConfigFactory\",\"properties\":[],\"methods\":[{\"name\":\"getConfig\",\"returnType\":{\"packageName\":\"@proteinjs/user-server\",\"name\":\"InviteConfig\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/user-server/InviteConfig\",\"typeParameters\":null,\"directParents\":null},\"isAsync\":false,\"isOptional\":false,\"isAbstract\":true,\"isStatic\":false,\"visibility\":\"public\",\"parameters\":[]}],\"typeParameters\":[],\"directParents\":[{\"packageName\":\"@proteinjs/reflection\",\"name\":\"Loadable\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/reflection/Loadable\",\"properties\":[],\"methods\":[],\"typeParameters\":[],\"directParents\":[]}],\"sourceType\":3}},{\"v\":\"@proteinjs/reflection/Loadable\"},{\"v\":\"@proteinjs/user-server/Signup\",\"value\":{\"packageName\":\"@proteinjs/user-server\",\"name\":\"Signup\",\"filePath\":\"/home/runner/work/user/user/packages/server/src/services/Signup.ts\",\"qualifiedName\":\"@proteinjs/user-server/Signup\",\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"properties\":[{\"name\":\"serviceMetadata\",\"type\":null,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\"}],\"methods\":[{\"name\":\"createUser\",\"returnType\":{\"packageName\":\"\",\"name\":\"Promise<void>\",\"filePath\":null,\"qualifiedName\":\"/Promise<void>\",\"typeParameters\":null,\"directParents\":null},\"isAsync\":true,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"parameters\":[{\"name\":\"user\",\"type\":{\"packageName\":\"@proteinjs/user\",\"name\":\"UserSignup\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/user/UserSignup\",\"typeParameters\":null,\"directParents\":null}},{\"name\":\"token\",\"type\":{\"packageName\":\"\",\"name\":\"string\",\"filePath\":null,\"qualifiedName\":\"/string\",\"typeParameters\":null,\"directParents\":null}}]},{\"name\":\"sendInvite\",\"returnType\":{\"packageName\":\"\",\"name\":\"Promise<SendInviteResponse>\",\"filePath\":null,\"qualifiedName\":\"/Promise<SendInviteResponse>\",\"typeParameters\":null,\"directParents\":null},\"isAsync\":true,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"parameters\":[{\"name\":\"email\",\"type\":{\"packageName\":\"\",\"name\":\"string\",\"filePath\":null,\"qualifiedName\":\"/string\",\"typeParameters\":null,\"directParents\":null}}]},{\"name\":\"revokeInvite\",\"returnType\":{\"packageName\":\"\",\"name\":\"Promise<void>\",\"filePath\":null,\"qualifiedName\":\"/Promise<void>\",\"typeParameters\":null,\"directParents\":null},\"isAsync\":true,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"parameters\":[{\"name\":\"email\",\"type\":{\"packageName\":\"\",\"name\":\"string\",\"filePath\":null,\"qualifiedName\":\"/string\",\"typeParameters\":null,\"directParents\":null}}]},{\"name\":\"initializeSignup\",\"returnType\":{\"packageName\":\"\",\"name\":\"Promise<InitializeSignupResponse>\",\"filePath\":null,\"qualifiedName\":\"/Promise<InitializeSignupResponse>\",\"typeParameters\":null,\"directParents\":null},\"isAsync\":true,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"parameters\":[{\"name\":\"inviteToken\",\"type\":{\"packageName\":\"\",\"name\":\"string | undefined\",\"filePath\":null,\"qualifiedName\":\"/string | undefined\",\"typeParameters\":null,\"directParents\":null}}]},{\"name\":\"lookupInvite\",\"returnType\":{\"packageName\":\"\",\"name\":\"Promise<InviteLookup>\",\"filePath\":null,\"qualifiedName\":\"/Promise<InviteLookup>\",\"typeParameters\":null,\"directParents\":null},\"isAsync\":true,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"private\",\"parameters\":[{\"name\":\"token\",\"type\":{\"packageName\":\"\",\"name\":\"string\",\"filePath\":null,\"qualifiedName\":\"/string\",\"typeParameters\":null,\"directParents\":null}}]}],\"typeParameters\":[],\"directParentInterfaces\":[{\"packageName\":\"@proteinjs/user\",\"name\":\"SignupService\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/user/SignupService\",\"properties\":[],\"methods\":[],\"typeParameters\":[],\"directParents\":[]}],\"directParentClasses\":[],\"sourceType\":2}},{\"v\":\"@proteinjs/user/SignupService\"},{\"v\":\"@proteinjs/user-server/UpdateUserInfo\",\"value\":{\"packageName\":\"@proteinjs/user-server\",\"name\":\"UpdateUserInfo\",\"filePath\":\"/home/runner/work/user/user/packages/server/src/services/UpdateUserInfo.ts\",\"qualifiedName\":\"@proteinjs/user-server/UpdateUserInfo\",\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"properties\":[{\"name\":\"AVATAR_SIZE\",\"type\":null,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":true,\"visibility\":\"private\"},{\"name\":\"AVATAR_JPEG_QUALITY\",\"type\":null,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":true,\"visibility\":\"private\"},{\"name\":\"MAX_AVATAR_PHOTO_BYTES\",\"type\":null,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":true,\"visibility\":\"private\"},{\"name\":\"ACCEPTED_AVATAR_MIME_TYPES\",\"type\":null,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":true,\"visibility\":\"private\"},{\"name\":\"MAX_AVATAR_EMOJI_LENGTH\",\"type\":null,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":true,\"visibility\":\"private\"},{\"name\":\"EMOJI_PATTERN\",\"type\":null,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":true,\"visibility\":\"private\"},{\"name\":\"serviceMetadata\",\"type\":null,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\"}],\"methods\":[{\"name\":\"updateName\",\"returnType\":{\"packageName\":\"\",\"name\":\"Promise<UpdatedUser>\",\"filePath\":null,\"qualifiedName\":\"/Promise<UpdatedUser>\",\"typeParameters\":null,\"directParents\":null},\"isAsync\":true,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"parameters\":[{\"name\":\"name\",\"type\":{\"packageName\":\"\",\"name\":\"string\",\"filePath\":null,\"qualifiedName\":\"/string\",\"typeParameters\":null,\"directParents\":null}}]},{\"name\":\"updatePassword\",\"returnType\":{\"packageName\":\"\",\"name\":\"Promise<UpdatePasswordResponse>\",\"filePath\":null,\"qualifiedName\":\"/Promise<UpdatePasswordResponse>\",\"typeParameters\":null,\"directParents\":null},\"isAsync\":true,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"parameters\":[{\"name\":\"currentPassword\",\"type\":{\"packageName\":\"\",\"name\":\"string\",\"filePath\":null,\"qualifiedName\":\"/string\",\"typeParameters\":null,\"directParents\":null}},{\"name\":\"newPassword\",\"type\":{\"packageName\":\"\",\"name\":\"string\",\"filePath\":null,\"qualifiedName\":\"/string\",\"typeParameters\":null,\"directParents\":null}}]},{\"name\":\"updateAvatarPhoto\",\"returnType\":{\"packageName\":\"\",\"name\":\"Promise<UpdatedUser>\",\"filePath\":null,\"qualifiedName\":\"/Promise<UpdatedUser>\",\"typeParameters\":null,\"directParents\":null},\"isAsync\":true,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"parameters\":[{\"name\":\"fileData\",\"type\":{\"packageName\":\"\",\"name\":\"string\",\"filePath\":null,\"qualifiedName\":\"/string\",\"typeParameters\":null,\"directParents\":null}},{\"name\":\"mimeType\",\"type\":{\"packageName\":\"\",\"name\":\"string\",\"filePath\":null,\"qualifiedName\":\"/string\",\"typeParameters\":null,\"directParents\":null}}]},{\"name\":\"updateAvatarEmoji\",\"returnType\":{\"packageName\":\"\",\"name\":\"Promise<UpdatedUser>\",\"filePath\":null,\"qualifiedName\":\"/Promise<UpdatedUser>\",\"typeParameters\":null,\"directParents\":null},\"isAsync\":true,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"parameters\":[{\"name\":\"emoji\",\"type\":{\"packageName\":\"\",\"name\":\"string\",\"filePath\":null,\"qualifiedName\":\"/string\",\"typeParameters\":null,\"directParents\":null}}]},{\"name\":\"clearAvatar\",\"returnType\":{\"packageName\":\"\",\"name\":\"Promise<UpdatedUser>\",\"filePath\":null,\"qualifiedName\":\"/Promise<UpdatedUser>\",\"typeParameters\":null,\"directParents\":null},\"isAsync\":true,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"public\",\"parameters\":[]},{\"name\":\"setAvatar\",\"returnType\":{\"packageName\":\"\",\"name\":\"Promise<UpdatedUser>\",\"filePath\":null,\"qualifiedName\":\"/Promise<UpdatedUser>\",\"typeParameters\":null,\"directParents\":null},\"isAsync\":true,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"private\",\"parameters\":[{\"name\":\"avatar\",\"type\":{\"packageName\":\"@proteinjs/user-server\",\"name\":\"{ avatarEmoji: string | null; avatarFileId: string | null }\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/user-server/{ avatarEmoji: string | null; avatarFileId: string | null }\",\"typeParameters\":null,\"directParents\":null}}]},{\"name\":\"saveUserInfo\",\"returnType\":{\"packageName\":\"\",\"name\":\"Promise<UpdatedUser>\",\"filePath\":null,\"qualifiedName\":\"/Promise<UpdatedUser>\",\"typeParameters\":null,\"directParents\":null},\"isAsync\":true,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"private\",\"parameters\":[{\"name\":\"changes\",\"type\":{\"packageName\":\"\",\"name\":\"Partial<User>\",\"filePath\":null,\"qualifiedName\":\"/Partial<User>\",\"typeParameters\":null,\"directParents\":null}}]},{\"name\":\"toAvatarJpeg\",\"returnType\":{\"packageName\":\"\",\"name\":\"Promise<Buffer>\",\"filePath\":null,\"qualifiedName\":\"/Promise<Buffer>\",\"typeParameters\":null,\"directParents\":null},\"isAsync\":true,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"private\",\"parameters\":[{\"name\":\"imageBytes\",\"type\":{\"packageName\":\"\",\"name\":\"Buffer\",\"filePath\":null,\"qualifiedName\":\"/Buffer\",\"typeParameters\":null,\"directParents\":null}},{\"name\":\"mimeType\",\"type\":{\"packageName\":\"\",\"name\":\"string\",\"filePath\":null,\"qualifiedName\":\"/string\",\"typeParameters\":null,\"directParents\":null}}]},{\"name\":\"decodeHeic\",\"returnType\":{\"packageName\":\"\",\"name\":\"Promise<sharp.Sharp>\",\"filePath\":null,\"qualifiedName\":\"/Promise<sharp.Sharp>\",\"typeParameters\":null,\"directParents\":null},\"isAsync\":true,\"isOptional\":false,\"isAbstract\":false,\"isStatic\":false,\"visibility\":\"private\",\"parameters\":[{\"name\":\"imageBytes\",\"type\":{\"packageName\":\"\",\"name\":\"Buffer\",\"filePath\":null,\"qualifiedName\":\"/Buffer\",\"typeParameters\":null,\"directParents\":null}}]}],\"typeParameters\":[],\"directParentInterfaces\":[{\"packageName\":\"@proteinjs/user\",\"name\":\"UpdateUserInfoService\",\"filePath\":null,\"qualifiedName\":\"@proteinjs/user/UpdateUserInfoService\",\"properties\":[],\"methods\":[],\"typeParameters\":[],\"directParents\":[]}],\"directParentClasses\":[],\"sourceType\":2}},{\"v\":\"@proteinjs/user/UpdateUserInfoService\"}],\"edges\":[{\"v\":\"@proteinjs/user-server/DbSessionStore\",\"w\":\"express-session/Store\",\"value\":\"extends class\"},{\"v\":\"@proteinjs/user-server/SocketIOSessionWatcher\",\"w\":\"@proteinjs/db/TableWatcher\",\"value\":\"implements interface\"},{\"v\":\"@proteinjs/user-server/userCache\",\"w\":\"@proteinjs/server-api/SessionDataCache\",\"value\":\"has type\"},{\"v\":\"@proteinjs/user-server/BackfillUserRolesArray\",\"w\":\"@proteinjs/db/SourceRecordLoader\",\"value\":\"implements interface\"},{\"v\":\"@proteinjs/user-server/avatar\",\"w\":\"@proteinjs/server-api/Route\",\"value\":\"has type\"},{\"v\":\"@proteinjs/user-server/devLogin\",\"w\":\"@proteinjs/server-api/Route\",\"value\":\"has type\"},{\"v\":\"@proteinjs/user-server/executePasswordReset\",\"w\":\"@proteinjs/server-api/Route\",\"value\":\"has type\"},{\"v\":\"@proteinjs/user-server/initiatePasswordReset\",\"w\":\"@proteinjs/server-api/Route\",\"value\":\"has type\"},{\"v\":\"@proteinjs/user-server/login\",\"w\":\"@proteinjs/server-api/Route\",\"value\":\"has type\"},{\"v\":\"@proteinjs/user-server/logout\",\"w\":\"@proteinjs/server-api/Route\",\"value\":\"has type\"},{\"v\":\"@proteinjs/user-server/validateResetPasswordToken\",\"w\":\"@proteinjs/server-api/Route\",\"value\":\"has type\"},{\"v\":\"@proteinjs/user-server/AccessInvite\",\"w\":\"@proteinjs/user/AccessInviteService\",\"value\":\"implements interface\"},{\"v\":\"@proteinjs/user-server/Roles\",\"w\":\"@proteinjs/user/RolesService\",\"value\":\"implements interface\"},{\"v\":\"@proteinjs/user-server/DefaultInviteConfigFactory\",\"w\":\"@proteinjs/reflection/Loadable\",\"value\":\"extends interface\"},{\"v\":\"@proteinjs/user-server/Signup\",\"w\":\"@proteinjs/user/SignupService\",\"value\":\"implements interface\"},{\"v\":\"@proteinjs/user-server/UpdateUserInfo\",\"w\":\"@proteinjs/user/UpdateUserInfoService\",\"value\":\"implements interface\"}]}";
|
|
30
27
|
/** Generate Source Links */
|
|
31
28
|
var DbSessionStore_1 = require("../src/authentication/DbSessionStore");
|
|
32
29
|
var SocketIOSessionWatcher_1 = require("../src/authentication/SocketIOSessionWatcher");
|
|
33
30
|
var userCache_1 = require("../src/authorization/userCache");
|
|
31
|
+
var BackfillUserRolesArray_1 = require("../src/migrations/BackfillUserRolesArray");
|
|
32
|
+
var avatar_1 = require("../src/routes/avatar");
|
|
34
33
|
var devLogin_1 = require("../src/routes/devLogin");
|
|
35
34
|
var executePasswordReset_1 = require("../src/routes/executePasswordReset");
|
|
36
35
|
var initiatePasswordReset_1 = require("../src/routes/initiatePasswordReset");
|
|
@@ -41,11 +40,12 @@ var AccessInvite_1 = require("../src/services/AccessInvite");
|
|
|
41
40
|
var Roles_1 = require("../src/services/Roles");
|
|
42
41
|
var Signup_1 = require("../src/services/Signup");
|
|
43
42
|
var UpdateUserInfo_1 = require("../src/services/UpdateUserInfo");
|
|
44
|
-
var BackfillUserRolesArray_1 = require("../src/migrations/BackfillUserRolesArray");
|
|
45
43
|
var sourceLinks = {
|
|
46
44
|
'@proteinjs/user-server/DbSessionStore': DbSessionStore_1.DbSessionStore,
|
|
47
45
|
'@proteinjs/user-server/SocketIOSessionWatcher': SocketIOSessionWatcher_1.SocketIOSessionWatcher,
|
|
48
46
|
'@proteinjs/user-server/userCache': userCache_1.userCache,
|
|
47
|
+
'@proteinjs/user-server/BackfillUserRolesArray': BackfillUserRolesArray_1.BackfillUserRolesArray,
|
|
48
|
+
'@proteinjs/user-server/avatar': avatar_1.avatar,
|
|
49
49
|
'@proteinjs/user-server/devLogin': devLogin_1.devLogin,
|
|
50
50
|
'@proteinjs/user-server/executePasswordReset': executePasswordReset_1.executePasswordReset,
|
|
51
51
|
'@proteinjs/user-server/initiatePasswordReset': initiatePasswordReset_1.initiatePasswordReset,
|
|
@@ -56,7 +56,6 @@ var sourceLinks = {
|
|
|
56
56
|
'@proteinjs/user-server/Roles': Roles_1.Roles,
|
|
57
57
|
'@proteinjs/user-server/Signup': Signup_1.Signup,
|
|
58
58
|
'@proteinjs/user-server/UpdateUserInfo': UpdateUserInfo_1.UpdateUserInfo,
|
|
59
|
-
'@proteinjs/user-server/BackfillUserRolesArray': BackfillUserRolesArray_1.BackfillUserRolesArray,
|
|
60
59
|
};
|
|
61
60
|
/** Load Source Graph and Links */
|
|
62
61
|
var reflection_1 = require("@proteinjs/reflection");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../generated/index.ts"],"names":[],"mappings":";AAAA,oCAAoC;;;;;;;;;;;;;;;;AAEpC,yBAAuB;AACvB,mCAAiC;AACjC,6BAA2B;AAC3B,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../generated/index.ts"],"names":[],"mappings":";AAAA,oCAAoC;;;;;;;;;;;;;;;;AAEpC,yBAAuB;AACvB,8BAA4B;AAC5B,mCAAiC;AACjC,6BAA2B;AAC3B,6BAA2B;AAC3B,iCAA+B;AAC/B,2BAAyB;AAGzB,4BAA4B;AAE5B,IAAM,WAAW,GAAG,628BAA628B,CAAC;AAGl48B,4BAA4B;AAE5B,uEAAsE;AACtE,uFAAsF;AACtF,4DAA2D;AAC3D,mFAAkF;AAClF,+CAA8C;AAC9C,mDAAkD;AAClD,2EAA0E;AAC1E,6EAA4E;AAC5E,6CAA4C;AAC5C,+CAA8C;AAC9C,uFAAsF;AACtF,6DAA4D;AAC5D,+CAA8C;AAC9C,iDAAgD;AAChD,iEAAgE;AAEhE,IAAM,WAAW,GAAG;IACnB,uCAAuC,EAAE,+BAAc;IACvD,+CAA+C,EAAE,+CAAsB;IACvE,kCAAkC,EAAE,qBAAS;IAC7C,+CAA+C,EAAE,+CAAsB;IACvE,+BAA+B,EAAE,eAAM;IACvC,iCAAiC,EAAE,mBAAQ;IAC3C,6CAA6C,EAAE,2CAAoB;IACnE,8CAA8C,EAAE,6CAAqB;IACrE,8BAA8B,EAAE,aAAK;IACrC,+BAA+B,EAAE,eAAM;IACvC,mDAAmD,EAAE,uDAA0B;IAC/E,qCAAqC,EAAE,2BAAY;IACnD,8BAA8B,EAAE,aAAK;IACrC,+BAA+B,EAAE,eAAM;IACvC,uCAAuC,EAAE,+BAAc;CACvD,CAAC;AAGF,kCAAkC;AAElC,oDAAyD;AACzD,6BAAgB,CAAC,KAAK,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;AAGjD,2CAAyB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DbSessionStore.d.ts","sourceRoot":"","sources":["../../../src/authentication/DbSessionStore.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"DbSessionStore.d.ts","sourceRoot":"","sources":["../../../src/authentication/DbSessionStore.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAMxC,qBAAa,cAAe,SAAQ,KAAK;IACvC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAuB;IAC3D;yEACqE;IACrE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,cAAc,CAAiB;IACvD,OAAO,CAAC,MAAM,CAA+C;IAC7D,OAAO,CAAC,WAAW,CAA6B;;IAchD,GAAG,cAAe,MAAM,cAAc,GAAG,YAAY,QAAQ,WAAW,GAAG,IAAI,KAAK,IAAI,UAUtF;IAEF,GAAG,cAAe,MAAM,WAAW,QAAQ,WAAW,iBAAgB,GAAG,KAAK,IAAI,uBAiBhF;IAEF,KAAK,cAAe,MAAM,WAAW,QAAQ,WAAW,iBAAgB,GAAG,KAAK,IAAI,uBA8BlF;IAEF,6EAA6E;IAC7E,OAAO,CAAC,MAAM,CAAC,kBAAkB;IAKjC;;;OAGG;IACH,OAAO,cAAe,MAAM,iBAAgB,GAAG,KAAK,IAAI,uBAWtD;YAEY,cAAc;YA2Cd,KAAK;CAYpB"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Route } from '@proteinjs/server-api';
|
|
2
|
+
/**
|
|
3
|
+
* Shared avatar serving: `GET /avatar/:userId?v=<avatarFileId>` — any logged-in user can render
|
|
4
|
+
* any user's avatar photo (attribution in shared spaces). File rows are ScopedRecords and
|
|
5
|
+
* `GET /file/:id` reads through the OWNER's scope, so other users cannot fetch an avatar through
|
|
6
|
+
* it; this route is the deliberate, narrow door instead.
|
|
7
|
+
*
|
|
8
|
+
* System-read surface is exactly: the user row (for `avatarFileId`), that one file row (for the
|
|
9
|
+
* Content-Type), and its bytes. The file id is never taken from the request — only the id stored
|
|
10
|
+
* on the user row is served, so this can never read arbitrary files. `:userId` is a keyed lookup
|
|
11
|
+
* (no path/filesystem interpretation).
|
|
12
|
+
*
|
|
13
|
+
* Cache contract (mirrored by `avatarRoute` in @proteinjs/user routes.ts): the path is stable per
|
|
14
|
+
* user, so responses carry `max-age=86400, immutable`; clients bust with `?v=<avatarFileId>`,
|
|
15
|
+
* which changes on every photo update. Users with an emoji avatar or no avatar answer 404 — the
|
|
16
|
+
* client renders emoji/initials from the user record; this route serves photos only.
|
|
17
|
+
*/
|
|
18
|
+
export declare const avatar: Route;
|
|
19
|
+
//# sourceMappingURL=avatar.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"avatar.d.ts","sourceRoot":"","sources":["../../../src/routes/avatar.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAQ9C;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,MAAM,EAAE,KAgCpB,CAAC"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
12
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
13
|
+
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
14
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
15
|
+
function step(op) {
|
|
16
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
17
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
18
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
19
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
20
|
+
switch (op[0]) {
|
|
21
|
+
case 0: case 1: t = op; break;
|
|
22
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
23
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
24
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
25
|
+
default:
|
|
26
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
27
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
28
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
29
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
30
|
+
if (t[2]) _.ops.pop();
|
|
31
|
+
_.trys.pop(); continue;
|
|
32
|
+
}
|
|
33
|
+
op = body.call(thisArg, _);
|
|
34
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
35
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.avatar = void 0;
|
|
40
|
+
var db_1 = require("@proteinjs/db");
|
|
41
|
+
var user_1 = require("@proteinjs/user");
|
|
42
|
+
var db_file_1 = require("@proteinjs/db-file");
|
|
43
|
+
var logger_1 = require("@proteinjs/logger");
|
|
44
|
+
var logger = new logger_1.Logger({ name: 'avatarRoute' });
|
|
45
|
+
/**
|
|
46
|
+
* Shared avatar serving: `GET /avatar/:userId?v=<avatarFileId>` — any logged-in user can render
|
|
47
|
+
* any user's avatar photo (attribution in shared spaces). File rows are ScopedRecords and
|
|
48
|
+
* `GET /file/:id` reads through the OWNER's scope, so other users cannot fetch an avatar through
|
|
49
|
+
* it; this route is the deliberate, narrow door instead.
|
|
50
|
+
*
|
|
51
|
+
* System-read surface is exactly: the user row (for `avatarFileId`), that one file row (for the
|
|
52
|
+
* Content-Type), and its bytes. The file id is never taken from the request — only the id stored
|
|
53
|
+
* on the user row is served, so this can never read arbitrary files. `:userId` is a keyed lookup
|
|
54
|
+
* (no path/filesystem interpretation).
|
|
55
|
+
*
|
|
56
|
+
* Cache contract (mirrored by `avatarRoute` in @proteinjs/user routes.ts): the path is stable per
|
|
57
|
+
* user, so responses carry `max-age=86400, immutable`; clients bust with `?v=<avatarFileId>`,
|
|
58
|
+
* which changes on every photo update. Users with an emoji avatar or no avatar answer 404 — the
|
|
59
|
+
* client renders emoji/initials from the user record; this route serves photos only.
|
|
60
|
+
*/
|
|
61
|
+
exports.avatar = {
|
|
62
|
+
path: '/avatar/:userId',
|
|
63
|
+
method: 'get',
|
|
64
|
+
onRequest: function (request, response) { return __awaiter(void 0, void 0, void 0, function () {
|
|
65
|
+
var userId, user, file, fileDataBase64, error_1;
|
|
66
|
+
return __generator(this, function (_a) {
|
|
67
|
+
switch (_a.label) {
|
|
68
|
+
case 0:
|
|
69
|
+
if (!user_1.UserAuth.isLoggedIn()) {
|
|
70
|
+
response.status(401).send('User not logged in');
|
|
71
|
+
return [2 /*return*/];
|
|
72
|
+
}
|
|
73
|
+
_a.label = 1;
|
|
74
|
+
case 1:
|
|
75
|
+
_a.trys.push([1, 5, , 6]);
|
|
76
|
+
userId = request.params.userId;
|
|
77
|
+
return [4 /*yield*/, (0, db_1.getDbAsSystem)().get(user_1.tables.User, { id: userId })];
|
|
78
|
+
case 2:
|
|
79
|
+
user = _a.sent();
|
|
80
|
+
if (!user || !user.avatarFileId) {
|
|
81
|
+
response.status(404).send('No avatar photo');
|
|
82
|
+
return [2 /*return*/];
|
|
83
|
+
}
|
|
84
|
+
return [4 /*yield*/, (0, user_1.getScopedDbAsSystem)().get(db_file_1.tables.File, { id: user.avatarFileId })];
|
|
85
|
+
case 3:
|
|
86
|
+
file = _a.sent();
|
|
87
|
+
if (!file) {
|
|
88
|
+
response.status(404).send('No avatar photo');
|
|
89
|
+
return [2 /*return*/];
|
|
90
|
+
}
|
|
91
|
+
return [4 /*yield*/, new db_file_1.FileStorage().getFileData(file.id)];
|
|
92
|
+
case 4:
|
|
93
|
+
fileDataBase64 = _a.sent();
|
|
94
|
+
response.setHeader('Content-Type', file.type);
|
|
95
|
+
response.setHeader('Cache-Control', 'public, max-age=86400, immutable');
|
|
96
|
+
response.send(Buffer.from(fileDataBase64, 'base64'));
|
|
97
|
+
return [3 /*break*/, 6];
|
|
98
|
+
case 5:
|
|
99
|
+
error_1 = _a.sent();
|
|
100
|
+
logger.error({ message: 'Failed to serve avatar', error: error_1 });
|
|
101
|
+
response.status(500).send('Internal Server Error');
|
|
102
|
+
return [3 /*break*/, 6];
|
|
103
|
+
case 6: return [2 /*return*/];
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
}); },
|
|
107
|
+
};
|
|
108
|
+
//# sourceMappingURL=avatar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"avatar.js","sourceRoot":"","sources":["../../../src/routes/avatar.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA,oCAA8C;AAC9C,wCAAwE;AACxE,8CAA6E;AAC7E,4CAA2C;AAE3C,IAAM,MAAM,GAAG,IAAI,eAAM,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC,CAAC;AAEnD;;;;;;;;;;;;;;;GAeG;AACU,QAAA,MAAM,GAAU;IAC3B,IAAI,EAAE,iBAAiB;IACvB,MAAM,EAAE,KAAK;IACb,SAAS,EAAE,UAAO,OAAO,EAAE,QAAQ;;;;;oBACjC,IAAI,CAAC,eAAQ,CAAC,UAAU,EAAE,EAAE;wBAC1B,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;wBAChD,sBAAO;qBACR;;;;oBAGO,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC;oBACxB,qBAAM,IAAA,kBAAa,GAAE,CAAC,GAAG,CAAC,aAAM,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,EAAA;;oBAA7D,IAAI,GAAG,SAAsD;oBACnE,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE;wBAC/B,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;wBAC7C,sBAAO;qBACR;oBAEY,qBAAM,IAAA,0BAAmB,GAAQ,CAAC,GAAG,CAAC,gBAAU,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,YAAY,EAAE,CAAC,EAAA;;oBAAxF,IAAI,GAAG,SAAiF;oBAC9F,IAAI,CAAC,IAAI,EAAE;wBACT,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;wBAC7C,sBAAO;qBACR;oBAEsB,qBAAM,IAAI,qBAAW,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC,EAAA;;oBAA7D,cAAc,GAAG,SAA4C;oBACnE,QAAQ,CAAC,SAAS,CAAC,cAAc,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;oBAC9C,QAAQ,CAAC,SAAS,CAAC,eAAe,EAAE,kCAAkC,CAAC,CAAC;oBACxE,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,cAAc,EAAE,QAAQ,CAAC,CAAC,CAAC;;;;oBAErD,MAAM,CAAC,KAAK,CAAC,EAAE,OAAO,EAAE,wBAAwB,EAAE,KAAK,SAAA,EAAE,CAAC,CAAC;oBAC3D,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;;;;;SAEtD;CACF,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"devLogin.d.ts","sourceRoot":"","sources":["../../../src/routes/devLogin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAK9C;;;;;;;;;GASG;AACH,eAAO,MAAM,QAAQ,EAAE,
|
|
1
|
+
{"version":3,"file":"devLogin.d.ts","sourceRoot":"","sources":["../../../src/routes/devLogin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAK9C;;;;;;;;;GASG;AACH,eAAO,MAAM,QAAQ,EAAE,KAmBtB,CAAC"}
|
|
@@ -65,6 +65,17 @@ exports.devLogin = {
|
|
|
65
65
|
}
|
|
66
66
|
return [4 /*yield*/, new Promise(function (resolve) { return request.login(email, resolve); })];
|
|
67
67
|
case 1:
|
|
68
|
+
_b.sent();
|
|
69
|
+
// Explicit save before redirecting: with a DB-backed session store, save-on-response-end
|
|
70
|
+
// races the redirected GET / — the follow-up request can read the session row before the
|
|
71
|
+
// write commits and render the login page (observed: first /dev/login load lands on /login,
|
|
72
|
+
// second succeeds). Awaiting the store write closes the race.
|
|
73
|
+
return [4 /*yield*/, new Promise(function (resolve) { return request.session.save(resolve); })];
|
|
74
|
+
case 2:
|
|
75
|
+
// Explicit save before redirecting: with a DB-backed session store, save-on-response-end
|
|
76
|
+
// races the redirected GET / — the follow-up request can read the session row before the
|
|
77
|
+
// write commits and render the login page (observed: first /dev/login load lands on /login,
|
|
78
|
+
// second succeeds). Awaiting the store write closes the race.
|
|
68
79
|
_b.sent();
|
|
69
80
|
logger.info({ message: 'Dev auto-login session established', obj: { email: email } });
|
|
70
81
|
response.redirect('/');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"devLogin.js","sourceRoot":"","sources":["../../../src/routes/devLogin.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA,4CAA2C;AAE3C,IAAM,MAAM,GAAG,IAAI,eAAM,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC;AAEhD;;;;;;;;;GASG;AACU,QAAA,QAAQ,GAAU;IAC7B,IAAI,EAAE,YAAY;IAClB,MAAM,EAAE,KAAK;IACb,SAAS,EAAE,UAAO,OAAY,EAAE,QAAQ;;;;;;oBAChC,KAAK,GAAG,CAAC,MAAA,OAAO,CAAC,GAAG,CAAC,oBAAoB,mCAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;oBAC9D,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,CAAC,KAAK,EAAE;wBACtC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;wBAC5B,sBAAO;qBACR;oBAED,qBAAM,IAAI,OAAO,CAAC,UAAC,OAAO,IAAK,OAAA,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,OAAO,CAAC,EAA7B,CAA6B,CAAC,EAAA;;oBAA7D,SAA6D,CAAC;oBAC9D,MAAM,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,oCAAoC,EAAE,GAAG,EAAE,EAAE,KAAK,OAAA,EAAE,EAAE,CAAC,CAAC;oBAC/E,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;;;;SACxB;CACF,CAAC"}
|
|
1
|
+
{"version":3,"file":"devLogin.js","sourceRoot":"","sources":["../../../src/routes/devLogin.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA,4CAA2C;AAE3C,IAAM,MAAM,GAAG,IAAI,eAAM,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC;AAEhD;;;;;;;;;GASG;AACU,QAAA,QAAQ,GAAU;IAC7B,IAAI,EAAE,YAAY;IAClB,MAAM,EAAE,KAAK;IACb,SAAS,EAAE,UAAO,OAAY,EAAE,QAAQ;;;;;;oBAChC,KAAK,GAAG,CAAC,MAAA,OAAO,CAAC,GAAG,CAAC,oBAAoB,mCAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;oBAC9D,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,CAAC,KAAK,EAAE;wBACtC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;wBAC5B,sBAAO;qBACR;oBAED,qBAAM,IAAI,OAAO,CAAC,UAAC,OAAO,IAAK,OAAA,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,OAAO,CAAC,EAA7B,CAA6B,CAAC,EAAA;;oBAA7D,SAA6D,CAAC;oBAC9D,yFAAyF;oBACzF,yFAAyF;oBACzF,4FAA4F;oBAC5F,8DAA8D;oBAC9D,qBAAM,IAAI,OAAO,CAAC,UAAC,OAAO,IAAK,OAAA,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,EAA7B,CAA6B,CAAC,EAAA;;oBAJ7D,yFAAyF;oBACzF,yFAAyF;oBACzF,4FAA4F;oBAC5F,8DAA8D;oBAC9D,SAA6D,CAAC;oBAC9D,MAAM,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,oCAAoC,EAAE,GAAG,EAAE,EAAE,KAAK,OAAA,EAAE,EAAE,CAAC,CAAC;oBAC/E,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;;;;SACxB;CACF,CAAC"}
|
|
@@ -1,11 +1,49 @@
|
|
|
1
|
-
import { UpdatePasswordResponse, UpdateUserInfoService } from '@proteinjs/user';
|
|
1
|
+
import { UpdatePasswordResponse, UpdatedUser, UpdateUserInfoService } from '@proteinjs/user';
|
|
2
2
|
export declare class UpdateUserInfo implements UpdateUserInfoService {
|
|
3
|
+
/** Stored avatar photos are exactly this: cover-cropped square JPEG. */
|
|
4
|
+
private static readonly AVATAR_SIZE;
|
|
5
|
+
private static readonly AVATAR_JPEG_QUALITY;
|
|
6
|
+
private static readonly MAX_AVATAR_PHOTO_BYTES;
|
|
7
|
+
private static readonly ACCEPTED_AVATAR_MIME_TYPES;
|
|
8
|
+
/** One emoji (possibly a ZWJ/flag/keycap sequence) — a handful of code units, never a sentence. */
|
|
9
|
+
private static readonly MAX_AVATAR_EMOJI_LENGTH;
|
|
10
|
+
/** Constructed (not a literal) because tsconfig targets es5; runs on Node, which supports `\p`. */
|
|
11
|
+
private static readonly EMOJI_PATTERN;
|
|
3
12
|
serviceMetadata: {
|
|
4
13
|
auth: {
|
|
5
14
|
allUsers: boolean;
|
|
6
15
|
};
|
|
7
16
|
};
|
|
8
|
-
updateName(name: string): Promise<
|
|
17
|
+
updateName(name: string): Promise<UpdatedUser>;
|
|
9
18
|
updatePassword(currentPassword: string, newPassword: string): Promise<UpdatePasswordResponse>;
|
|
19
|
+
updateAvatarPhoto(fileData: string, mimeType: string): Promise<UpdatedUser>;
|
|
20
|
+
updateAvatarEmoji(emoji: string): Promise<UpdatedUser>;
|
|
21
|
+
clearAvatar(): Promise<UpdatedUser>;
|
|
22
|
+
/**
|
|
23
|
+
* The single door to the avatar columns — every mutation assigns BOTH, which is what enforces
|
|
24
|
+
* the exactly-one-active invariant (photo OR emoji, never both). Also the previous photo's
|
|
25
|
+
* cleanup point: an avatar file the user row no longer points to is unreachable (the /avatar
|
|
26
|
+
* route serves only the id on the user row), so it is deleted here, after the row moves off it.
|
|
27
|
+
*/
|
|
28
|
+
private setAvatar;
|
|
29
|
+
/**
|
|
30
|
+
* The one path every user-info mutation persists through: writes the changes AND refreshes the
|
|
31
|
+
* server session cache in the same stroke. userCache serializes the user into session data at
|
|
32
|
+
* request start; a bare DB write leaves every read through UserRepo in the same context — and
|
|
33
|
+
* long-lived contexts that keep their session data (sockets) — serving the STALE user until
|
|
34
|
+
* re-login (the rename wart). Fusing persist + refresh here means no future mutation can
|
|
35
|
+
* reintroduce that class of staleness.
|
|
36
|
+
*/
|
|
37
|
+
private saveUserInfo;
|
|
38
|
+
/**
|
|
39
|
+
* Minimal avatar pipeline: decode, auto-orient from EXIF, cover-crop square, re-encode JPEG.
|
|
40
|
+
* sharp drops metadata (EXIF orientation/GPS) on re-encode by default — the stored avatar
|
|
41
|
+
* carries no camera metadata. HEIC/HEIF (default iPhone camera format) is decoded with WASM
|
|
42
|
+
* libheif (`heic-decode`) because sharp's prebuilt libvips has no HEVC decoder. NOTE: this
|
|
43
|
+
* duplicates the HEIC-normalization approach of chat-server's FileTransformer, which this
|
|
44
|
+
* package cannot import (layering) — future extraction target: a shared image-transform seam.
|
|
45
|
+
*/
|
|
46
|
+
private toAvatarJpeg;
|
|
47
|
+
private decodeHeic;
|
|
10
48
|
}
|
|
11
49
|
//# sourceMappingURL=UpdateUserInfo.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UpdateUserInfo.d.ts","sourceRoot":"","sources":["../../../src/services/UpdateUserInfo.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"UpdateUserInfo.d.ts","sourceRoot":"","sources":["../../../src/services/UpdateUserInfo.ts"],"names":[],"mappings":"AAKA,OAAO,EAA0B,sBAAsB,EAAE,WAAW,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAGrH,qBAAa,cAAe,YAAW,qBAAqB;IAC1D,wEAAwE;IACxE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAO;IAC1C,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,mBAAmB,CAAM;IACjD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,sBAAsB,CAAoB;IAClE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,0BAA0B,CAMhD;IACF,mGAAmG;IACnG,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,uBAAuB,CAAM;IACrD,mGAAmG;IACnG,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAiF;IAE/G,eAAe;;;;MAIpB;IAEI,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAI9C,cAAc,CAAC,eAAe,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,sBAAsB,CAAC;IAmD7F,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAoB3E,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IActD,WAAW,IAAI,OAAO,CAAC,WAAW,CAAC;IAIzC;;;;;OAKG;YACW,SAAS;IAWvB;;;;;;;OAOG;YACW,YAAY;IAW1B;;;;;;;OAOG;YACW,YAAY;YAWZ,UAAU;CAMzB"}
|