@proteinjs/user-server 1.9.1 → 1.10.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 +16 -0
- package/dist/generated/index.js +1 -1
- package/dist/generated/index.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -1
- package/dist/index.js.map +1 -1
- package/dist/src/services/UpdateUserInfo.d.ts +27 -5
- package/dist/src/services/UpdateUserInfo.d.ts.map +1 -1
- package/dist/src/services/UpdateUserInfo.js +72 -13
- package/dist/src/services/UpdateUserInfo.js.map +1 -1
- package/dist/test/AvatarPhotoFidelity.test.d.ts +2 -0
- package/dist/test/AvatarPhotoFidelity.test.d.ts.map +1 -0
- package/dist/test/AvatarPhotoFidelity.test.js +221 -0
- package/dist/test/AvatarPhotoFidelity.test.js.map +1 -0
- package/dist/test/UpdateUserInfoAvatar.test.js +5 -4
- package/dist/test/UpdateUserInfoAvatar.test.js.map +1 -1
- package/dist/test/avatarRoute.test.js +4 -2
- package/dist/test/avatarRoute.test.js.map +1 -1
- package/generated/index.ts +1 -1
- package/index.ts +4 -1
- package/package.json +3 -3
- package/src/services/UpdateUserInfo.ts +72 -8
- package/test/AvatarPhotoFidelity.test.ts +109 -0
- package/test/UpdateUserInfoAvatar.test.ts +7 -4
- package/test/avatarRoute.test.ts +4 -2
package/generated/index.ts
CHANGED
|
@@ -11,7 +11,7 @@ import '@proteinjs/user';
|
|
|
11
11
|
/** Generate Source Graph */
|
|
12
12
|
|
|
13
13
|
const sourceGraph =
|
|
14
|
-
'{"options":{"directed":true,"multigraph":false,"compound":false},"nodes":[{"v":"@proteinjs/user-server/DbSessionStore","value":{"packageName":"@proteinjs/user-server","name":"DbSessionStore","filePath":"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":"/\'human\' | \'machine\'"},{"v":"@proteinjs/user-server/SocketIOSessionWatcher","value":{"packageName":"@proteinjs/user-server","name":"SocketIOSessionWatcher","filePath":"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/UserStatusTableWatcher","value":{"packageName":"@proteinjs/user-server","name":"UserStatusTableWatcher","filePath":"src/authentication/UserStatusTableWatcher.ts","qualifiedName":"@proteinjs/user-server/UserStatusTableWatcher","isAbstract":false,"isStatic":false,"visibility":"public","properties":[{"name":"logger","type":null,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"private"}],"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<User>","filePath":null,"qualifiedName":"/Table<User>","typeParameters":null,"directParents":null},"isAsync":false,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public","parameters":[]},{"name":"afterUpdate","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":"recordUpdateCount","type":{"packageName":"","name":"number","filePath":null,"qualifiedName":"/number","typeParameters":null,"directParents":null}},{"name":"record","type":{"packageName":"","name":"Partial<T>","filePath":null,"qualifiedName":"/Partial<T>","typeParameters":null,"directParents":null}},{"name":"qb","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/User"],"directParents":[]}],"directParentClasses":[],"sourceType":2}},{"v":"@proteinjs/user-server/userCache","value":{"packageName":"@proteinjs/user-server","name":"userCache","filePath":"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/DefaultAccountDeletionRequestedEmailConfigFactory","value":{"packageName":"@proteinjs/user-server","name":"DefaultAccountDeletionRequestedEmailConfigFactory","filePath":"src/emails/AccountDeletionEmailConfigs.ts","qualifiedName":"@proteinjs/user-server/DefaultAccountDeletionRequestedEmailConfigFactory","properties":[],"methods":[{"name":"getConfig","returnType":{"packageName":"@proteinjs/user-server","name":"AccountDeletionRequestedEmailConfig","filePath":null,"qualifiedName":"@proteinjs/user-server/AccountDeletionRequestedEmailConfig","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/DefaultAccountDeletedEmailConfigFactory","value":{"packageName":"@proteinjs/user-server","name":"DefaultAccountDeletedEmailConfigFactory","filePath":"src/emails/AccountDeletionEmailConfigs.ts","qualifiedName":"@proteinjs/user-server/DefaultAccountDeletedEmailConfigFactory","properties":[],"methods":[{"name":"getConfig","returnType":{"packageName":"@proteinjs/user-server","name":"AccountDeletedEmailConfig","filePath":null,"qualifiedName":"@proteinjs/user-server/AccountDeletedEmailConfig","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/user-server/BackfillUserRolesArray","value":{"packageName":"@proteinjs/user-server","name":"BackfillUserRolesArray","filePath":"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":"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":"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":"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":"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":"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":"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/signup","value":{"packageName":"@proteinjs/user-server","name":"signup","filePath":"src/routes/signup.ts","qualifiedName":"@proteinjs/user-server/signup","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":"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":"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/AccountDeletion","value":{"packageName":"@proteinjs/user-server","name":"AccountDeletion","filePath":"src/services/AccountDeletion.ts","qualifiedName":"@proteinjs/user-server/AccountDeletion","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"},{"name":"logger","type":null,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"private"}],"methods":[{"name":"requestDeletion","returnType":{"packageName":"","name":"Promise<{ purgeAfter: Moment }>","filePath":null,"qualifiedName":"/Promise<{ purgeAfter: Moment }>","typeParameters":null,"directParents":null},"isAsync":true,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public","parameters":[{"name":"password","type":{"packageName":"","name":"string","filePath":null,"qualifiedName":"/string","typeParameters":null,"directParents":null}}]},{"name":"cancelPendingDeletion","returnType":{"packageName":"","name":"Promise<\'not-pending\' | \'restored\' | \'purging\'>","filePath":null,"qualifiedName":"/Promise<\'not-pending\' | \'restored\' | \'purging\'>","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":"reauthenticateSessionUser","returnType":{"packageName":"","name":"Promise<User>","filePath":null,"qualifiedName":"/Promise<User>","typeParameters":null,"directParents":null},"isAsync":true,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"private","parameters":[{"name":"password","type":{"packageName":"","name":"string","filePath":null,"qualifiedName":"/string","typeParameters":null,"directParents":null}}]},{"name":"createDeletionManifest","returnType":{"packageName":"","name":"Promise<AccountDeletionRecord>","filePath":null,"qualifiedName":"/Promise<AccountDeletionRecord>","typeParameters":null,"directParents":null},"isAsync":true,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"private","parameters":[{"name":"db","type":{"packageName":"@proteinjs/db","name":"Db","filePath":null,"qualifiedName":"@proteinjs/db/Db","typeParameters":null,"directParents":null}},{"name":"user","type":{"packageName":"@proteinjs/user","name":"User","filePath":null,"qualifiedName":"@proteinjs/user/User","typeParameters":null,"directParents":null}}]},{"name":"deleteGrantsById","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":"db","type":{"packageName":"@proteinjs/db","name":"Db","filePath":null,"qualifiedName":"@proteinjs/db/Db","typeParameters":null,"directParents":null}},{"name":"grantIds","type":{"packageName":"","name":"string[]","filePath":null,"qualifiedName":"/string[]","typeParameters":null,"directParents":null}}]},{"name":"restoreManifestGrants","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":"db","type":{"packageName":"@proteinjs/db","name":"Db","filePath":null,"qualifiedName":"@proteinjs/db/Db","typeParameters":null,"directParents":null}},{"name":"manifestGrants","type":{"packageName":"","name":"ManifestGrant[]","filePath":null,"qualifiedName":"/ManifestGrant[]","typeParameters":null,"directParents":null}}]},{"name":"toManifestGrant","returnType":{"packageName":"@proteinjs/user","name":"ManifestGrant","filePath":null,"qualifiedName":"@proteinjs/user/ManifestGrant","typeParameters":null,"directParents":null},"isAsync":false,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"private","parameters":[{"name":"grant","type":{"packageName":"@proteinjs/user","name":"AccessGrant","filePath":null,"qualifiedName":"@proteinjs/user/AccessGrant","typeParameters":null,"directParents":null}}]},{"name":"referenceId","returnType":{"packageName":"","name":"string","filePath":null,"qualifiedName":"/string","typeParameters":null,"directParents":null},"isAsync":false,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"private","parameters":[{"name":"reference","type":{"packageName":"","name":"Reference<any>","filePath":null,"qualifiedName":"/Reference<any>","typeParameters":null,"directParents":null}},{"name":"grantId","type":{"packageName":"","name":"string","filePath":null,"qualifiedName":"/string","typeParameters":null,"directParents":null}}]},{"name":"gracePeriodDays","returnType":{"packageName":"","name":"number","filePath":null,"qualifiedName":"/number","typeParameters":null,"directParents":null},"isAsync":false,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"private","parameters":[]},{"name":"chunk","returnType":{"packageName":"","name":"T[][]","filePath":null,"qualifiedName":"/T[][]","typeParameters":null,"directParents":null},"isAsync":false,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"private","parameters":[{"name":"items","type":{"packageName":"","name":"T[]","filePath":null,"qualifiedName":"/T[]","typeParameters":null,"directParents":null}},{"name":"size","type":{"packageName":"","name":"number","filePath":null,"qualifiedName":"/number","typeParameters":null,"directParents":null}}]}],"typeParameters":[],"directParentInterfaces":[{"packageName":"@proteinjs/user","name":"AccountDeletionService","filePath":null,"qualifiedName":"@proteinjs/user/AccountDeletionService","properties":[],"methods":[],"typeParameters":[],"directParents":[]}],"directParentClasses":[],"sourceType":2}},{"v":"@proteinjs/user/AccountDeletionService"},{"v":"@proteinjs/user-server/MachineCredentials","value":{"packageName":"@proteinjs/user-server","name":"MachineCredentials","filePath":"src/services/MachineCredentials.ts","qualifiedName":"@proteinjs/user-server/MachineCredentials","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":"listMachineAccounts","returnType":{"packageName":"","name":"Promise<MachineAccountView[]>","filePath":null,"qualifiedName":"/Promise<MachineAccountView[]>","typeParameters":null,"directParents":null},"isAsync":true,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public","parameters":[]},{"name":"mintCredential","returnType":{"packageName":"","name":"Promise<MintedMachineCredential>","filePath":null,"qualifiedName":"/Promise<MintedMachineCredential>","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}}]}],"typeParameters":[],"directParentInterfaces":[{"packageName":"@proteinjs/user","name":"MachineCredentialsService","filePath":null,"qualifiedName":"@proteinjs/user/MachineCredentialsService","properties":[],"methods":[],"typeParameters":[],"directParents":[]}],"directParentClasses":[],"sourceType":2}},{"v":"@proteinjs/user/MachineCredentialsService"},{"v":"@proteinjs/user-server/Roles","value":{"packageName":"@proteinjs/user-server","name":"Roles","filePath":"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/SetUserStatus","value":{"packageName":"@proteinjs/user-server","name":"SetUserStatus","filePath":"src/services/SetUserStatus.ts","qualifiedName":"@proteinjs/user-server/SetUserStatus","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":"setUserStatus","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":"status","type":{"packageName":"@proteinjs/user","name":"UserStatus","filePath":null,"qualifiedName":"@proteinjs/user/UserStatus","typeParameters":null,"directParents":null}}]}],"typeParameters":[],"directParentInterfaces":[{"packageName":"@proteinjs/user","name":"SetUserStatusService","filePath":null,"qualifiedName":"@proteinjs/user/SetUserStatusService","properties":[],"methods":[],"typeParameters":[],"directParents":[]}],"directParentClasses":[],"sourceType":2}},{"v":"@proteinjs/user/SetUserStatusService"},{"v":"@proteinjs/user-server/DefaultInviteConfigFactory","value":{"packageName":"@proteinjs/user-server","name":"DefaultInviteConfigFactory","filePath":"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/user-server/Signup","value":{"packageName":"@proteinjs/user-server","name":"Signup","filePath":"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<CreateUserResult>","filePath":null,"qualifiedName":"/Promise<CreateUserResult>","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":"createAccount","returnType":{"packageName":"","name":"Promise<\'created\' | \'exists\'>","filePath":null,"qualifiedName":"/Promise<\'created\' | \'exists\'>","typeParameters":null,"directParents":null},"isAsync":true,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public","parameters":[{"name":"account","type":{"packageName":"@proteinjs/user-server","name":"{\\n name: string;\\n email: string;\\n password: string;\\n emailVerified: boolean;\\n invitedBy: User[\'invitedBy\'];\\n }","filePath":null,"qualifiedName":"@proteinjs/user-server/{\\n name: string;\\n email: string;\\n password: string;\\n emailVerified: boolean;\\n invitedBy: User[\'invitedBy\'];\\n }","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":"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/UserStatusTableWatcher","w":"@proteinjs/db/TableWatcher","value":"implements interface"},{"v":"@proteinjs/user-server/userCache","w":"@proteinjs/server-api/SessionDataCache","value":"has type"},{"v":"@proteinjs/user-server/DefaultAccountDeletionRequestedEmailConfigFactory","w":"@proteinjs/reflection/Loadable","value":"extends interface"},{"v":"@proteinjs/user-server/DefaultAccountDeletedEmailConfigFactory","w":"@proteinjs/reflection/Loadable","value":"extends interface"},{"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/signup","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/AccountDeletion","w":"@proteinjs/user/AccountDeletionService","value":"implements interface"},{"v":"@proteinjs/user-server/MachineCredentials","w":"@proteinjs/user/MachineCredentialsService","value":"implements interface"},{"v":"@proteinjs/user-server/Roles","w":"@proteinjs/user/RolesService","value":"implements interface"},{"v":"@proteinjs/user-server/SetUserStatus","w":"@proteinjs/user/SetUserStatusService","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"}]}';
|
|
14
|
+
'{"options":{"directed":true,"multigraph":false,"compound":false},"nodes":[{"v":"@proteinjs/user-server/DbSessionStore","value":{"packageName":"@proteinjs/user-server","name":"DbSessionStore","filePath":"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":"/\'human\' | \'machine\'"},{"v":"@proteinjs/user-server/SocketIOSessionWatcher","value":{"packageName":"@proteinjs/user-server","name":"SocketIOSessionWatcher","filePath":"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/UserStatusTableWatcher","value":{"packageName":"@proteinjs/user-server","name":"UserStatusTableWatcher","filePath":"src/authentication/UserStatusTableWatcher.ts","qualifiedName":"@proteinjs/user-server/UserStatusTableWatcher","isAbstract":false,"isStatic":false,"visibility":"public","properties":[{"name":"logger","type":null,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"private"}],"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<User>","filePath":null,"qualifiedName":"/Table<User>","typeParameters":null,"directParents":null},"isAsync":false,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public","parameters":[]},{"name":"afterUpdate","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":"recordUpdateCount","type":{"packageName":"","name":"number","filePath":null,"qualifiedName":"/number","typeParameters":null,"directParents":null}},{"name":"record","type":{"packageName":"","name":"Partial<T>","filePath":null,"qualifiedName":"/Partial<T>","typeParameters":null,"directParents":null}},{"name":"qb","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/User"],"directParents":[]}],"directParentClasses":[],"sourceType":2}},{"v":"@proteinjs/user-server/userCache","value":{"packageName":"@proteinjs/user-server","name":"userCache","filePath":"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/DefaultAccountDeletionRequestedEmailConfigFactory","value":{"packageName":"@proteinjs/user-server","name":"DefaultAccountDeletionRequestedEmailConfigFactory","filePath":"src/emails/AccountDeletionEmailConfigs.ts","qualifiedName":"@proteinjs/user-server/DefaultAccountDeletionRequestedEmailConfigFactory","properties":[],"methods":[{"name":"getConfig","returnType":{"packageName":"@proteinjs/user-server","name":"AccountDeletionRequestedEmailConfig","filePath":null,"qualifiedName":"@proteinjs/user-server/AccountDeletionRequestedEmailConfig","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/DefaultAccountDeletedEmailConfigFactory","value":{"packageName":"@proteinjs/user-server","name":"DefaultAccountDeletedEmailConfigFactory","filePath":"src/emails/AccountDeletionEmailConfigs.ts","qualifiedName":"@proteinjs/user-server/DefaultAccountDeletedEmailConfigFactory","properties":[],"methods":[{"name":"getConfig","returnType":{"packageName":"@proteinjs/user-server","name":"AccountDeletedEmailConfig","filePath":null,"qualifiedName":"@proteinjs/user-server/AccountDeletedEmailConfig","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/user-server/BackfillUserRolesArray","value":{"packageName":"@proteinjs/user-server","name":"BackfillUserRolesArray","filePath":"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":"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":"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":"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":"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":"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":"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/signup","value":{"packageName":"@proteinjs/user-server","name":"signup","filePath":"src/routes/signup.ts","qualifiedName":"@proteinjs/user-server/signup","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":"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":"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/AccountDeletion","value":{"packageName":"@proteinjs/user-server","name":"AccountDeletion","filePath":"src/services/AccountDeletion.ts","qualifiedName":"@proteinjs/user-server/AccountDeletion","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"},{"name":"logger","type":null,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"private"}],"methods":[{"name":"requestDeletion","returnType":{"packageName":"","name":"Promise<{ purgeAfter: Moment }>","filePath":null,"qualifiedName":"/Promise<{ purgeAfter: Moment }>","typeParameters":null,"directParents":null},"isAsync":true,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public","parameters":[{"name":"password","type":{"packageName":"","name":"string","filePath":null,"qualifiedName":"/string","typeParameters":null,"directParents":null}}]},{"name":"cancelPendingDeletion","returnType":{"packageName":"","name":"Promise<\'not-pending\' | \'restored\' | \'purging\'>","filePath":null,"qualifiedName":"/Promise<\'not-pending\' | \'restored\' | \'purging\'>","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":"reauthenticateSessionUser","returnType":{"packageName":"","name":"Promise<User>","filePath":null,"qualifiedName":"/Promise<User>","typeParameters":null,"directParents":null},"isAsync":true,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"private","parameters":[{"name":"password","type":{"packageName":"","name":"string","filePath":null,"qualifiedName":"/string","typeParameters":null,"directParents":null}}]},{"name":"createDeletionManifest","returnType":{"packageName":"","name":"Promise<AccountDeletionRecord>","filePath":null,"qualifiedName":"/Promise<AccountDeletionRecord>","typeParameters":null,"directParents":null},"isAsync":true,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"private","parameters":[{"name":"db","type":{"packageName":"@proteinjs/db","name":"Db","filePath":null,"qualifiedName":"@proteinjs/db/Db","typeParameters":null,"directParents":null}},{"name":"user","type":{"packageName":"@proteinjs/user","name":"User","filePath":null,"qualifiedName":"@proteinjs/user/User","typeParameters":null,"directParents":null}}]},{"name":"deleteGrantsById","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":"db","type":{"packageName":"@proteinjs/db","name":"Db","filePath":null,"qualifiedName":"@proteinjs/db/Db","typeParameters":null,"directParents":null}},{"name":"grantIds","type":{"packageName":"","name":"string[]","filePath":null,"qualifiedName":"/string[]","typeParameters":null,"directParents":null}}]},{"name":"restoreManifestGrants","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":"db","type":{"packageName":"@proteinjs/db","name":"Db","filePath":null,"qualifiedName":"@proteinjs/db/Db","typeParameters":null,"directParents":null}},{"name":"manifestGrants","type":{"packageName":"","name":"ManifestGrant[]","filePath":null,"qualifiedName":"/ManifestGrant[]","typeParameters":null,"directParents":null}}]},{"name":"toManifestGrant","returnType":{"packageName":"@proteinjs/user","name":"ManifestGrant","filePath":null,"qualifiedName":"@proteinjs/user/ManifestGrant","typeParameters":null,"directParents":null},"isAsync":false,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"private","parameters":[{"name":"grant","type":{"packageName":"@proteinjs/user","name":"AccessGrant","filePath":null,"qualifiedName":"@proteinjs/user/AccessGrant","typeParameters":null,"directParents":null}}]},{"name":"referenceId","returnType":{"packageName":"","name":"string","filePath":null,"qualifiedName":"/string","typeParameters":null,"directParents":null},"isAsync":false,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"private","parameters":[{"name":"reference","type":{"packageName":"","name":"Reference<any>","filePath":null,"qualifiedName":"/Reference<any>","typeParameters":null,"directParents":null}},{"name":"grantId","type":{"packageName":"","name":"string","filePath":null,"qualifiedName":"/string","typeParameters":null,"directParents":null}}]},{"name":"gracePeriodDays","returnType":{"packageName":"","name":"number","filePath":null,"qualifiedName":"/number","typeParameters":null,"directParents":null},"isAsync":false,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"private","parameters":[]},{"name":"chunk","returnType":{"packageName":"","name":"T[][]","filePath":null,"qualifiedName":"/T[][]","typeParameters":null,"directParents":null},"isAsync":false,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"private","parameters":[{"name":"items","type":{"packageName":"","name":"T[]","filePath":null,"qualifiedName":"/T[]","typeParameters":null,"directParents":null}},{"name":"size","type":{"packageName":"","name":"number","filePath":null,"qualifiedName":"/number","typeParameters":null,"directParents":null}}]}],"typeParameters":[],"directParentInterfaces":[{"packageName":"@proteinjs/user","name":"AccountDeletionService","filePath":null,"qualifiedName":"@proteinjs/user/AccountDeletionService","properties":[],"methods":[],"typeParameters":[],"directParents":[]}],"directParentClasses":[],"sourceType":2}},{"v":"@proteinjs/user/AccountDeletionService"},{"v":"@proteinjs/user-server/MachineCredentials","value":{"packageName":"@proteinjs/user-server","name":"MachineCredentials","filePath":"src/services/MachineCredentials.ts","qualifiedName":"@proteinjs/user-server/MachineCredentials","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":"listMachineAccounts","returnType":{"packageName":"","name":"Promise<MachineAccountView[]>","filePath":null,"qualifiedName":"/Promise<MachineAccountView[]>","typeParameters":null,"directParents":null},"isAsync":true,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public","parameters":[]},{"name":"mintCredential","returnType":{"packageName":"","name":"Promise<MintedMachineCredential>","filePath":null,"qualifiedName":"/Promise<MintedMachineCredential>","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}}]}],"typeParameters":[],"directParentInterfaces":[{"packageName":"@proteinjs/user","name":"MachineCredentialsService","filePath":null,"qualifiedName":"@proteinjs/user/MachineCredentialsService","properties":[],"methods":[],"typeParameters":[],"directParents":[]}],"directParentClasses":[],"sourceType":2}},{"v":"@proteinjs/user/MachineCredentialsService"},{"v":"@proteinjs/user-server/Roles","value":{"packageName":"@proteinjs/user-server","name":"Roles","filePath":"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/SetUserStatus","value":{"packageName":"@proteinjs/user-server","name":"SetUserStatus","filePath":"src/services/SetUserStatus.ts","qualifiedName":"@proteinjs/user-server/SetUserStatus","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":"setUserStatus","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":"status","type":{"packageName":"@proteinjs/user","name":"UserStatus","filePath":null,"qualifiedName":"@proteinjs/user/UserStatus","typeParameters":null,"directParents":null}}]}],"typeParameters":[],"directParentInterfaces":[{"packageName":"@proteinjs/user","name":"SetUserStatusService","filePath":null,"qualifiedName":"@proteinjs/user/SetUserStatusService","properties":[],"methods":[],"typeParameters":[],"directParents":[]}],"directParentClasses":[],"sourceType":2}},{"v":"@proteinjs/user/SetUserStatusService"},{"v":"@proteinjs/user-server/DefaultInviteConfigFactory","value":{"packageName":"@proteinjs/user-server","name":"DefaultInviteConfigFactory","filePath":"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/user-server/Signup","value":{"packageName":"@proteinjs/user-server","name":"Signup","filePath":"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<CreateUserResult>","filePath":null,"qualifiedName":"/Promise<CreateUserResult>","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":"createAccount","returnType":{"packageName":"","name":"Promise<\'created\' | \'exists\'>","filePath":null,"qualifiedName":"/Promise<\'created\' | \'exists\'>","typeParameters":null,"directParents":null},"isAsync":true,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"public","parameters":[{"name":"account","type":{"packageName":"@proteinjs/user-server","name":"{\\n name: string;\\n email: string;\\n password: string;\\n emailVerified: boolean;\\n invitedBy: User[\'invitedBy\'];\\n }","filePath":null,"qualifiedName":"@proteinjs/user-server/{\\n name: string;\\n email: string;\\n password: string;\\n emailVerified: boolean;\\n invitedBy: User[\'invitedBy\'];\\n }","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":"src/services/UpdateUserInfo.ts","qualifiedName":"@proteinjs/user-server/UpdateUserInfo","isAbstract":false,"isStatic":false,"visibility":"public","properties":[{"name":"AVATAR_MAX_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":"crop","type":{"packageName":"@proteinjs/user","name":"AvatarCrop","filePath":null,"qualifiedName":"@proteinjs/user/AvatarCrop","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":"crop","type":{"packageName":"@proteinjs/user","name":"AvatarCrop","filePath":null,"qualifiedName":"@proteinjs/user/AvatarCrop","typeParameters":null,"directParents":null}}]},{"name":"orientedDimensions","returnType":{"packageName":"","name":"Promise<{ width: number; height: number }>","filePath":null,"qualifiedName":"/Promise<{ width: number; height: number }>","typeParameters":null,"directParents":null},"isAsync":true,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"private","parameters":[{"name":"pipeline","type":{"packageName":"","name":"sharp.Sharp","filePath":null,"qualifiedName":"/sharp.Sharp","typeParameters":null,"directParents":null}}]},{"name":"clampCrop","returnType":{"packageName":"@proteinjs/user-server","name":"{ left: number; top: number; size: number }","filePath":null,"qualifiedName":"@proteinjs/user-server/{ left: number; top: number; size: number }","typeParameters":null,"directParents":null},"isAsync":false,"isOptional":false,"isAbstract":false,"isStatic":false,"visibility":"private","parameters":[{"name":"crop","type":{"packageName":"","name":"AvatarCrop | undefined","filePath":null,"qualifiedName":"/AvatarCrop | undefined","typeParameters":null,"directParents":null}},{"name":"width","type":{"packageName":"","name":"number","filePath":null,"qualifiedName":"/number","typeParameters":null,"directParents":null}},{"name":"height","type":{"packageName":"","name":"number","filePath":null,"qualifiedName":"/number","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/UserStatusTableWatcher","w":"@proteinjs/db/TableWatcher","value":"implements interface"},{"v":"@proteinjs/user-server/userCache","w":"@proteinjs/server-api/SessionDataCache","value":"has type"},{"v":"@proteinjs/user-server/DefaultAccountDeletionRequestedEmailConfigFactory","w":"@proteinjs/reflection/Loadable","value":"extends interface"},{"v":"@proteinjs/user-server/DefaultAccountDeletedEmailConfigFactory","w":"@proteinjs/reflection/Loadable","value":"extends interface"},{"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/signup","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/AccountDeletion","w":"@proteinjs/user/AccountDeletionService","value":"implements interface"},{"v":"@proteinjs/user-server/MachineCredentials","w":"@proteinjs/user/MachineCredentialsService","value":"implements interface"},{"v":"@proteinjs/user-server/Roles","w":"@proteinjs/user/RolesService","value":"implements interface"},{"v":"@proteinjs/user-server/SetUserStatus","w":"@proteinjs/user/SetUserStatusService","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"}]}';
|
|
15
15
|
|
|
16
16
|
/** Generate Source Links */
|
|
17
17
|
|
package/index.ts
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
export { createAuthentication } from './src/authentication/authenticate';
|
|
2
2
|
export * from './src/authentication/DbSessionStore';
|
|
3
|
-
|
|
3
|
+
// The Signup CLASS exports so consumer-app server code can drive the invite domain in-process
|
|
4
|
+
// (e.g. n3xa's invite-request resolution minting a real invite through sendInvite) — the same
|
|
5
|
+
// single owner the RPC door dispatches to, never a parallel invite-write path.
|
|
6
|
+
export { InviteConfig, DefaultInviteConfigFactory, Signup } from './src/services/Signup';
|
|
4
7
|
export { AccessInvite } from './src/services/AccessInvite';
|
|
5
8
|
export { AccountDeletion } from './src/services/AccountDeletion';
|
|
6
9
|
export * from './src/emails/AccountDeletionEmailConfigs';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@proteinjs/user-server",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.10.0",
|
|
4
4
|
"description": "User server components",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"@proteinjs/reflection": "^1.1.14",
|
|
30
30
|
"@proteinjs/server": "^3.5.1",
|
|
31
31
|
"@proteinjs/server-api": "^3.0.11",
|
|
32
|
-
"@proteinjs/user": "^1.10.
|
|
32
|
+
"@proteinjs/user": "^1.10.2",
|
|
33
33
|
"argon2": "^0.45.1",
|
|
34
34
|
"crypto-js": "4.0.0",
|
|
35
35
|
"express-session": "1.17.1",
|
|
@@ -58,5 +58,5 @@
|
|
|
58
58
|
},
|
|
59
59
|
"main": "./dist/generated/index.js",
|
|
60
60
|
"types": "./dist/generated/index.d.ts",
|
|
61
|
-
"gitHead": "
|
|
61
|
+
"gitHead": "e06f115edf4d2c0b9a2c8ac659bc28403a1f4afe"
|
|
62
62
|
}
|
|
@@ -2,13 +2,27 @@ import sharp from 'sharp';
|
|
|
2
2
|
import heicDecode from 'heic-decode';
|
|
3
3
|
import { getDbAsSystem } from '@proteinjs/db';
|
|
4
4
|
import { FileStorage } from '@proteinjs/db-file';
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
tables,
|
|
7
|
+
User,
|
|
8
|
+
UserRepo,
|
|
9
|
+
UpdatePasswordResponse,
|
|
10
|
+
UpdatedUser,
|
|
11
|
+
UpdateUserInfoService,
|
|
12
|
+
AvatarCrop,
|
|
13
|
+
} from '@proteinjs/user';
|
|
6
14
|
import { EmailSender, getDefaultPasswordUpdatedEmailConfigFactory } from '@proteinjs/email-server';
|
|
7
15
|
import { PasswordHasher } from '../authentication/PasswordHasher';
|
|
8
16
|
|
|
9
17
|
export class UpdateUserInfo implements UpdateUserInfoService {
|
|
10
|
-
/**
|
|
11
|
-
|
|
18
|
+
/**
|
|
19
|
+
* Stored avatar photos are square JPEGs capped at this edge — and never ENLARGED to it: a
|
|
20
|
+
* source (or crop) smaller than the cap keeps its honest pixel count. Upscaling a small photo
|
|
21
|
+
* to a fixed 512 invents pixels that read as permanent blur on every chip that renders it
|
|
22
|
+
* (the founder's fuzzy-avatar defect); the display layer downscales crisply from whatever
|
|
23
|
+
* honest size is stored.
|
|
24
|
+
*/
|
|
25
|
+
private static readonly AVATAR_MAX_SIZE = 512;
|
|
12
26
|
private static readonly AVATAR_JPEG_QUALITY = 85;
|
|
13
27
|
private static readonly MAX_AVATAR_PHOTO_BYTES = 10 * 1024 * 1024;
|
|
14
28
|
private static readonly ACCEPTED_AVATAR_MIME_TYPES = [
|
|
@@ -83,7 +97,7 @@ export class UpdateUserInfo implements UpdateUserInfoService {
|
|
|
83
97
|
};
|
|
84
98
|
}
|
|
85
99
|
|
|
86
|
-
async updateAvatarPhoto(fileData: string, mimeType: string): Promise<UpdatedUser> {
|
|
100
|
+
async updateAvatarPhoto(fileData: string, mimeType: string, crop?: AvatarCrop): Promise<UpdatedUser> {
|
|
87
101
|
if (!UpdateUserInfo.ACCEPTED_AVATAR_MIME_TYPES.includes(mimeType)) {
|
|
88
102
|
throw new Error(
|
|
89
103
|
`Unsupported avatar image type '${mimeType}'. Accepted: ${UpdateUserInfo.ACCEPTED_AVATAR_MIME_TYPES.join(', ')}`
|
|
@@ -95,7 +109,7 @@ export class UpdateUserInfo implements UpdateUserInfoService {
|
|
|
95
109
|
throw new Error(`Avatar photo is too large (max 10MB)`);
|
|
96
110
|
}
|
|
97
111
|
|
|
98
|
-
const jpeg = await this.toAvatarJpeg(imageBytes, mimeType);
|
|
112
|
+
const jpeg = await this.toAvatarJpeg(imageBytes, mimeType, crop);
|
|
99
113
|
const file = await new FileStorage().createFile(
|
|
100
114
|
{ name: 'avatar.jpg', type: 'image/jpeg', size: jpeg.length },
|
|
101
115
|
jpeg.toString('base64')
|
|
@@ -158,24 +172,74 @@ export class UpdateUserInfo implements UpdateUserInfoService {
|
|
|
158
172
|
}
|
|
159
173
|
|
|
160
174
|
/**
|
|
161
|
-
*
|
|
175
|
+
* THE avatar image pipeline — the only place avatar pixels are ever resampled: decode,
|
|
176
|
+
* auto-orient from EXIF, extract the crop frame (client-framed, or the centered square),
|
|
177
|
+
* one high-quality resize down to at most AVATAR_MAX_SIZE (never up), re-encode JPEG.
|
|
178
|
+
* Clients send ORIGINAL bytes; a client-side canvas export would resample a second time
|
|
179
|
+
* (and with the browser's low-default smoothing), baking blur into the stored master.
|
|
162
180
|
* sharp drops metadata (EXIF orientation/GPS) on re-encode by default — the stored avatar
|
|
163
181
|
* carries no camera metadata. HEIC/HEIF (default iPhone camera format) is decoded with WASM
|
|
164
182
|
* libheif (`heic-decode`) because sharp's prebuilt libvips has no HEVC decoder. NOTE: this
|
|
165
183
|
* duplicates the HEIC-normalization approach of chat-server's FileTransformer, which this
|
|
166
184
|
* package cannot import (layering) — future extraction target: a shared image-transform seam.
|
|
167
185
|
*/
|
|
168
|
-
private async toAvatarJpeg(imageBytes: Buffer, mimeType: string): Promise<Buffer> {
|
|
186
|
+
private async toAvatarJpeg(imageBytes: Buffer, mimeType: string, crop?: AvatarCrop): Promise<Buffer> {
|
|
169
187
|
const pipeline =
|
|
170
188
|
mimeType === 'image/heic' || mimeType === 'image/heif'
|
|
171
189
|
? await this.decodeHeic(imageBytes)
|
|
172
190
|
: sharp(imageBytes).rotate();
|
|
191
|
+
const { width, height } = await this.orientedDimensions(pipeline);
|
|
192
|
+
const frame = this.clampCrop(crop, width, height);
|
|
193
|
+
const target = Math.min(UpdateUserInfo.AVATAR_MAX_SIZE, frame.size);
|
|
173
194
|
return await pipeline
|
|
174
|
-
.
|
|
195
|
+
.extract({ left: frame.left, top: frame.top, width: frame.size, height: frame.size })
|
|
196
|
+
.resize(target, target, { fit: 'cover' })
|
|
175
197
|
.jpeg({ quality: UpdateUserInfo.AVATAR_JPEG_QUALITY })
|
|
176
198
|
.toBuffer();
|
|
177
199
|
}
|
|
178
200
|
|
|
201
|
+
/**
|
|
202
|
+
* The decoded image's dimensions in DISPLAYED (EXIF-oriented) pixel space — the space the
|
|
203
|
+
* client framed its crop in, and the space `.rotate()` makes `.extract` operate in.
|
|
204
|
+
* Orientations 5-8 transpose the encoded axes.
|
|
205
|
+
*/
|
|
206
|
+
private async orientedDimensions(pipeline: sharp.Sharp): Promise<{ width: number; height: number }> {
|
|
207
|
+
const metadata = await pipeline.metadata();
|
|
208
|
+
if (!metadata.width || !metadata.height) {
|
|
209
|
+
throw new Error(`Could not read avatar image dimensions`);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
const transposed = (metadata.orientation ?? 1) >= 5;
|
|
213
|
+
return {
|
|
214
|
+
width: transposed ? metadata.height : metadata.width,
|
|
215
|
+
height: transposed ? metadata.width : metadata.height,
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* Resolve the crop request against the real image: round to whole pixels and clamp fully
|
|
221
|
+
* inside the oriented bounds, staying square. Absent crop = the centered square (identical
|
|
222
|
+
* to the old `fit: cover` center-crop, so no-crop clients keep byte-equivalent behavior).
|
|
223
|
+
*/
|
|
224
|
+
private clampCrop(
|
|
225
|
+
crop: AvatarCrop | undefined,
|
|
226
|
+
width: number,
|
|
227
|
+
height: number
|
|
228
|
+
): { left: number; top: number; size: number } {
|
|
229
|
+
const maxSize = Math.min(width, height);
|
|
230
|
+
if (!crop) {
|
|
231
|
+
return { left: Math.floor((width - maxSize) / 2), top: Math.floor((height - maxSize) / 2), size: maxSize };
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
if (![crop.sx, crop.sy, crop.size].every(Number.isFinite)) {
|
|
235
|
+
throw new Error(`Avatar crop must be numeric`);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
const size = Math.min(Math.max(1, Math.round(crop.size)), maxSize);
|
|
239
|
+
const clampOffset = (value: number, max: number) => Math.min(Math.max(0, Math.round(value)), max);
|
|
240
|
+
return { left: clampOffset(crop.sx, width - size), top: clampOffset(crop.sy, height - size), size };
|
|
241
|
+
}
|
|
242
|
+
|
|
179
243
|
private async decodeHeic(imageBytes: Buffer): Promise<sharp.Sharp> {
|
|
180
244
|
const { width, height, data } = await heicDecode({ buffer: imageBytes });
|
|
181
245
|
return sharp(Buffer.from(data.buffer, data.byteOffset, data.byteLength), {
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import sharp from 'sharp';
|
|
4
|
+
import { UpdateUserInfo } from '../src/services/UpdateUserInfo';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Pixel-fidelity contract of THE avatar image pipeline (`toAvatarJpeg` — the only place avatar
|
|
8
|
+
* pixels are ever resampled), tested straight through the pipeline with no DB: a stored master
|
|
9
|
+
* never contains invented (enlarged) pixels, honors the client's crop frame exactly, and still
|
|
10
|
+
* caps large sources at 512. This is the categorical guard for the founder's fuzzy-avatar
|
|
11
|
+
* defect: a small source blown up to a fixed 512 master reads as permanent blur on every chip
|
|
12
|
+
* that renders it.
|
|
13
|
+
*
|
|
14
|
+
* Helpers are reached via the house typed-cast-on-an-instance pattern (no widening of the
|
|
15
|
+
* class surface).
|
|
16
|
+
*/
|
|
17
|
+
type AvatarPipelineInternals = {
|
|
18
|
+
toAvatarJpeg(imageBytes: Buffer, mimeType: string, crop?: { sx: number; sy: number; size: number }): Promise<Buffer>;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const pipeline = () => new UpdateUserInfo() as unknown as AvatarPipelineInternals;
|
|
22
|
+
|
|
23
|
+
const solidPng = async (width: number, height: number, rgb: { r: number; g: number; b: number }) =>
|
|
24
|
+
await sharp({ create: { width, height, channels: 3, background: rgb } })
|
|
25
|
+
.png()
|
|
26
|
+
.toBuffer();
|
|
27
|
+
|
|
28
|
+
const dimensionsOf = async (jpeg: Buffer) => {
|
|
29
|
+
const metadata = await sharp(jpeg).metadata();
|
|
30
|
+
return { width: metadata.width, height: metadata.height, format: metadata.format };
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
/** Average color of the whole output — crop-mapping assertions read regions, not single pixels. */
|
|
34
|
+
const averageColor = async (jpeg: Buffer) => {
|
|
35
|
+
const stats = await sharp(jpeg).stats();
|
|
36
|
+
const [r, g, b] = stats.channels.map((channel) => channel.mean);
|
|
37
|
+
return { r, g, b };
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
describe('avatar photo pixel fidelity', () => {
|
|
41
|
+
it('keeps a small source at its honest pixel count — never enlarged to the 512 cap', async () => {
|
|
42
|
+
const png = await solidPng(96, 96, { r: 200, g: 80, b: 40 });
|
|
43
|
+
|
|
44
|
+
const jpeg = await pipeline().toAvatarJpeg(png, 'image/png');
|
|
45
|
+
|
|
46
|
+
// The defect: the old pipeline resized EVERYTHING to a fixed 512 square, inventing 5x the
|
|
47
|
+
// pixels for a 96px source — permanent blur baked into the master.
|
|
48
|
+
expect(await dimensionsOf(jpeg)).toEqual({ width: 96, height: 96, format: 'jpeg' });
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it('center-crops a small non-square source to its honest square (no enlargement)', async () => {
|
|
52
|
+
const png = await solidPng(300, 200, { r: 10, g: 120, b: 210 });
|
|
53
|
+
|
|
54
|
+
const jpeg = await pipeline().toAvatarJpeg(png, 'image/png');
|
|
55
|
+
|
|
56
|
+
expect(await dimensionsOf(jpeg)).toEqual({ width: 200, height: 200, format: 'jpeg' });
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
it('extracts exactly the client-framed crop square', async () => {
|
|
60
|
+
// Left half blue, right half red; the client frames the right half.
|
|
61
|
+
const left = await solidPng(100, 100, { r: 20, g: 40, b: 220 });
|
|
62
|
+
const source = await sharp({
|
|
63
|
+
create: { width: 200, height: 100, channels: 3, background: { r: 220, g: 30, b: 30 } },
|
|
64
|
+
})
|
|
65
|
+
.composite([{ input: left, left: 0, top: 0 }])
|
|
66
|
+
.png()
|
|
67
|
+
.toBuffer();
|
|
68
|
+
|
|
69
|
+
const jpeg = await pipeline().toAvatarJpeg(source, 'image/png', { sx: 100, sy: 0, size: 100 });
|
|
70
|
+
|
|
71
|
+
expect(await dimensionsOf(jpeg)).toEqual({ width: 100, height: 100, format: 'jpeg' });
|
|
72
|
+
const color = await averageColor(jpeg);
|
|
73
|
+
expect(color.r).toBeGreaterThan(180);
|
|
74
|
+
expect(color.b).toBeLessThan(80);
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it('clamps an out-of-bounds crop inside the image, staying square', async () => {
|
|
78
|
+
const png = await solidPng(300, 200, { r: 90, g: 90, b: 90 });
|
|
79
|
+
|
|
80
|
+
const jpeg = await pipeline().toAvatarJpeg(png, 'image/png', { sx: 250, sy: 150, size: 120 });
|
|
81
|
+
|
|
82
|
+
expect(await dimensionsOf(jpeg)).toEqual({ width: 120, height: 120, format: 'jpeg' });
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
it('still lands a large source at the 512 cap', async () => {
|
|
86
|
+
const png = await solidPng(1024, 768, { r: 40, g: 160, b: 90 });
|
|
87
|
+
|
|
88
|
+
const jpeg = await pipeline().toAvatarJpeg(png, 'image/png');
|
|
89
|
+
|
|
90
|
+
expect(await dimensionsOf(jpeg)).toEqual({ width: 512, height: 512, format: 'jpeg' });
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
it('keeps a small HEIC source at its honest centered square (the WASM decode path)', async () => {
|
|
94
|
+
// The 96x64 fixture: centered 64px square, not an enlarged 512.
|
|
95
|
+
const heic = fs.readFileSync(path.join(__dirname, 'fixtures', 'fixture.heic'));
|
|
96
|
+
|
|
97
|
+
const jpeg = await pipeline().toAvatarJpeg(heic, 'image/heic');
|
|
98
|
+
|
|
99
|
+
expect(await dimensionsOf(jpeg)).toEqual({ width: 64, height: 64, format: 'jpeg' });
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
it('rejects a non-numeric crop in plain words', async () => {
|
|
103
|
+
const png = await solidPng(64, 64, { r: 10, g: 10, b: 10 });
|
|
104
|
+
|
|
105
|
+
await expect(pipeline().toAvatarJpeg(png, 'image/png', { sx: NaN, sy: 0, size: 32 })).rejects.toThrow(
|
|
106
|
+
'Avatar crop must be numeric'
|
|
107
|
+
);
|
|
108
|
+
});
|
|
109
|
+
});
|