@technomoron/apicore-server 1.0.0-beta.1

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.
Files changed (171) hide show
  1. package/LICENSE +21 -0
  2. package/dist/cjs/api-module.cjs +34 -0
  3. package/dist/cjs/api-module.d.ts +45 -0
  4. package/dist/cjs/apicore-server.cjs +1561 -0
  5. package/dist/cjs/apicore-server.d.ts +288 -0
  6. package/dist/cjs/auth-api/auth-module.cjs +1248 -0
  7. package/dist/cjs/auth-api/auth-module.d.ts +116 -0
  8. package/dist/cjs/auth-api/compat-auth-storage.cjs +128 -0
  9. package/dist/cjs/auth-api/compat-auth-storage.d.ts +57 -0
  10. package/dist/cjs/auth-api/mem-auth-store.cjs +121 -0
  11. package/dist/cjs/auth-api/mem-auth-store.d.ts +68 -0
  12. package/dist/cjs/auth-api/module.cjs +25 -0
  13. package/dist/cjs/auth-api/module.d.ts +20 -0
  14. package/dist/cjs/auth-api/schemas.cjs +171 -0
  15. package/dist/cjs/auth-api/schemas.d.ts +21 -0
  16. package/dist/cjs/auth-api/sql-auth-store.cjs +179 -0
  17. package/dist/cjs/auth-api/sql-auth-store.d.ts +87 -0
  18. package/dist/cjs/auth-api/storage.cjs +102 -0
  19. package/dist/cjs/auth-api/storage.d.ts +38 -0
  20. package/dist/cjs/auth-api/types.cjs +2 -0
  21. package/dist/cjs/auth-api/types.d.ts +34 -0
  22. package/dist/cjs/auth-api/user-id.cjs +47 -0
  23. package/dist/cjs/auth-api/user-id.d.ts +5 -0
  24. package/dist/cjs/auth-cookie-options.cjs +66 -0
  25. package/dist/cjs/auth-cookie-options.d.ts +13 -0
  26. package/dist/cjs/base/client-info.cjs +285 -0
  27. package/dist/cjs/base/client-info.d.ts +27 -0
  28. package/dist/cjs/base/error-utils.cjs +50 -0
  29. package/dist/cjs/base/error-utils.d.ts +16 -0
  30. package/dist/cjs/base/request-utils.cjs +27 -0
  31. package/dist/cjs/base/request-utils.d.ts +8 -0
  32. package/dist/cjs/index.cjs +51 -0
  33. package/dist/cjs/index.d.ts +34 -0
  34. package/dist/cjs/limiter/auth-rate-limiter.cjs +35 -0
  35. package/dist/cjs/limiter/auth-rate-limiter.d.ts +12 -0
  36. package/dist/cjs/limiter/fixed-window.cjs +41 -0
  37. package/dist/cjs/limiter/fixed-window.d.ts +11 -0
  38. package/dist/cjs/oauth/base.cjs +7 -0
  39. package/dist/cjs/oauth/base.d.ts +17 -0
  40. package/dist/cjs/oauth/memory.cjs +135 -0
  41. package/dist/cjs/oauth/memory.d.ts +22 -0
  42. package/dist/cjs/oauth/models.cjs +47 -0
  43. package/dist/cjs/oauth/models.d.ts +50 -0
  44. package/dist/cjs/oauth/sequelize.cjs +159 -0
  45. package/dist/cjs/oauth/sequelize.d.ts +30 -0
  46. package/dist/cjs/oauth/types.cjs +3 -0
  47. package/dist/cjs/oauth/types.d.ts +51 -0
  48. package/dist/cjs/passkey/base.cjs +7 -0
  49. package/dist/cjs/passkey/base.d.ts +28 -0
  50. package/dist/cjs/passkey/config.cjs +26 -0
  51. package/dist/cjs/passkey/config.d.ts +2 -0
  52. package/dist/cjs/passkey/memory.cjs +123 -0
  53. package/dist/cjs/passkey/memory.d.ts +34 -0
  54. package/dist/cjs/passkey/models.cjs +142 -0
  55. package/dist/cjs/passkey/models.d.ts +34 -0
  56. package/dist/cjs/passkey/sequelize.cjs +126 -0
  57. package/dist/cjs/passkey/sequelize.d.ts +42 -0
  58. package/dist/cjs/passkey/service.cjs +413 -0
  59. package/dist/cjs/passkey/service.d.ts +21 -0
  60. package/dist/cjs/passkey/types.cjs +2 -0
  61. package/dist/cjs/passkey/types.d.ts +84 -0
  62. package/dist/cjs/sequelize-utils.cjs +56 -0
  63. package/dist/cjs/sequelize-utils.d.ts +8 -0
  64. package/dist/cjs/token/base.cjs +120 -0
  65. package/dist/cjs/token/base.d.ts +46 -0
  66. package/dist/cjs/token/memory.cjs +234 -0
  67. package/dist/cjs/token/memory.d.ts +29 -0
  68. package/dist/cjs/token/sequelize.cjs +400 -0
  69. package/dist/cjs/token/sequelize.d.ts +58 -0
  70. package/dist/cjs/token/types.cjs +2 -0
  71. package/dist/cjs/token/types.d.ts +34 -0
  72. package/dist/cjs/upload/memory.cjs +92 -0
  73. package/dist/cjs/upload/memory.d.ts +17 -0
  74. package/dist/cjs/upload/tus-module.cjs +270 -0
  75. package/dist/cjs/upload/tus-module.d.ts +38 -0
  76. package/dist/cjs/upload/types.cjs +2 -0
  77. package/dist/cjs/upload/types.d.ts +28 -0
  78. package/dist/cjs/user/base.cjs +53 -0
  79. package/dist/cjs/user/base.d.ts +36 -0
  80. package/dist/cjs/user/memory.cjs +194 -0
  81. package/dist/cjs/user/memory.d.ts +37 -0
  82. package/dist/cjs/user/sequelize.cjs +194 -0
  83. package/dist/cjs/user/sequelize.d.ts +46 -0
  84. package/dist/cjs/user/types.cjs +2 -0
  85. package/dist/cjs/user/types.d.ts +11 -0
  86. package/dist/esm/api-module.d.ts +45 -0
  87. package/dist/esm/api-module.js +30 -0
  88. package/dist/esm/apicore-server.d.ts +288 -0
  89. package/dist/esm/apicore-server.js +1552 -0
  90. package/dist/esm/auth-api/auth-module.d.ts +116 -0
  91. package/dist/esm/auth-api/auth-module.js +1246 -0
  92. package/dist/esm/auth-api/compat-auth-storage.d.ts +57 -0
  93. package/dist/esm/auth-api/compat-auth-storage.js +124 -0
  94. package/dist/esm/auth-api/mem-auth-store.d.ts +68 -0
  95. package/dist/esm/auth-api/mem-auth-store.js +117 -0
  96. package/dist/esm/auth-api/module.d.ts +20 -0
  97. package/dist/esm/auth-api/module.js +21 -0
  98. package/dist/esm/auth-api/schemas.d.ts +21 -0
  99. package/dist/esm/auth-api/schemas.js +168 -0
  100. package/dist/esm/auth-api/sql-auth-store.d.ts +87 -0
  101. package/dist/esm/auth-api/sql-auth-store.js +175 -0
  102. package/dist/esm/auth-api/storage.d.ts +38 -0
  103. package/dist/esm/auth-api/storage.js +98 -0
  104. package/dist/esm/auth-api/types.d.ts +34 -0
  105. package/dist/esm/auth-api/types.js +1 -0
  106. package/dist/esm/auth-api/user-id.d.ts +5 -0
  107. package/dist/esm/auth-api/user-id.js +41 -0
  108. package/dist/esm/auth-cookie-options.d.ts +13 -0
  109. package/dist/esm/auth-cookie-options.js +63 -0
  110. package/dist/esm/base/client-info.d.ts +27 -0
  111. package/dist/esm/base/client-info.js +282 -0
  112. package/dist/esm/base/error-utils.d.ts +16 -0
  113. package/dist/esm/base/error-utils.js +44 -0
  114. package/dist/esm/base/request-utils.d.ts +8 -0
  115. package/dist/esm/base/request-utils.js +23 -0
  116. package/dist/esm/index.d.ts +34 -0
  117. package/dist/esm/index.js +21 -0
  118. package/dist/esm/limiter/auth-rate-limiter.d.ts +12 -0
  119. package/dist/esm/limiter/auth-rate-limiter.js +32 -0
  120. package/dist/esm/limiter/fixed-window.d.ts +11 -0
  121. package/dist/esm/limiter/fixed-window.js +37 -0
  122. package/dist/esm/oauth/base.d.ts +17 -0
  123. package/dist/esm/oauth/base.js +3 -0
  124. package/dist/esm/oauth/memory.d.ts +22 -0
  125. package/dist/esm/oauth/memory.js +128 -0
  126. package/dist/esm/oauth/models.d.ts +50 -0
  127. package/dist/esm/oauth/models.js +38 -0
  128. package/dist/esm/oauth/sequelize.d.ts +30 -0
  129. package/dist/esm/oauth/sequelize.js +148 -0
  130. package/dist/esm/oauth/types.d.ts +51 -0
  131. package/dist/esm/oauth/types.js +2 -0
  132. package/dist/esm/passkey/base.d.ts +28 -0
  133. package/dist/esm/passkey/base.js +3 -0
  134. package/dist/esm/passkey/config.d.ts +2 -0
  135. package/dist/esm/passkey/config.js +23 -0
  136. package/dist/esm/passkey/memory.d.ts +34 -0
  137. package/dist/esm/passkey/memory.js +119 -0
  138. package/dist/esm/passkey/models.d.ts +34 -0
  139. package/dist/esm/passkey/models.js +135 -0
  140. package/dist/esm/passkey/sequelize.d.ts +42 -0
  141. package/dist/esm/passkey/sequelize.js +122 -0
  142. package/dist/esm/passkey/service.d.ts +21 -0
  143. package/dist/esm/passkey/service.js +376 -0
  144. package/dist/esm/passkey/types.d.ts +84 -0
  145. package/dist/esm/passkey/types.js +1 -0
  146. package/dist/esm/sequelize-utils.d.ts +8 -0
  147. package/dist/esm/sequelize-utils.js +47 -0
  148. package/dist/esm/token/base.d.ts +46 -0
  149. package/dist/esm/token/base.js +113 -0
  150. package/dist/esm/token/memory.d.ts +29 -0
  151. package/dist/esm/token/memory.js +230 -0
  152. package/dist/esm/token/sequelize.d.ts +58 -0
  153. package/dist/esm/token/sequelize.js +396 -0
  154. package/dist/esm/token/types.d.ts +34 -0
  155. package/dist/esm/token/types.js +1 -0
  156. package/dist/esm/upload/memory.d.ts +17 -0
  157. package/dist/esm/upload/memory.js +86 -0
  158. package/dist/esm/upload/tus-module.d.ts +38 -0
  159. package/dist/esm/upload/tus-module.js +266 -0
  160. package/dist/esm/upload/types.d.ts +28 -0
  161. package/dist/esm/upload/types.js +1 -0
  162. package/dist/esm/user/base.d.ts +36 -0
  163. package/dist/esm/user/base.js +46 -0
  164. package/dist/esm/user/memory.d.ts +37 -0
  165. package/dist/esm/user/memory.js +190 -0
  166. package/dist/esm/user/sequelize.d.ts +46 -0
  167. package/dist/esm/user/sequelize.js +188 -0
  168. package/dist/esm/user/types.d.ts +11 -0
  169. package/dist/esm/user/types.js +1 -0
  170. package/docs/swagger/openapi.json +2162 -0
  171. package/package.json +131 -0
@@ -0,0 +1,171 @@
1
+ "use strict";
2
+ /**
3
+ * JSON Schema definitions for auth module routes.
4
+ * These are the runtime validation source-of-truth; TypeScript interfaces
5
+ * in auth-module.ts remain for handler-internal typing only.
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.oauthTokenBodySchema = exports.oauthAuthorizeBodySchema = exports.oauthStartBodySchema = exports.oauthProviderParamsSchema = exports.deleteImpersonationQuerySchema = exports.impersonateBodySchema = exports.passkeyCredentialParamsSchema = exports.passkeyVerifyBodySchema = exports.passkeyChallengeBodySchema = exports.whoamiBodySchema = exports.logoutBodySchema = exports.refreshBodySchema = exports.loginBodySchema = void 0;
9
+ /* ------------------------------------------------------------------ */
10
+ /* Shared fragments */
11
+ /* ------------------------------------------------------------------ */
12
+ const tokenMetadataProperties = {
13
+ domain: { type: 'string' },
14
+ fingerprint: { type: 'string' },
15
+ label: { type: 'string' },
16
+ browser: { type: 'string' },
17
+ device: { type: 'string' },
18
+ ip: { type: 'string' },
19
+ os: { type: 'string' }
20
+ };
21
+ const keepSessionProperty = {
22
+ keepSession: { type: ['boolean', 'number', 'string'] }
23
+ };
24
+ function authIdentifierProperty(name) {
25
+ return { [name]: { type: ['string', 'number'] } };
26
+ }
27
+ /* ------------------------------------------------------------------ */
28
+ /* Auth route schemas */
29
+ /* ------------------------------------------------------------------ */
30
+ exports.loginBodySchema = {
31
+ type: 'object',
32
+ required: ['login', 'password'],
33
+ properties: {
34
+ login: { type: 'string', minLength: 1 },
35
+ password: { type: 'string', minLength: 1 },
36
+ ...tokenMetadataProperties,
37
+ ...keepSessionProperty
38
+ },
39
+ additionalProperties: true
40
+ };
41
+ exports.refreshBodySchema = {
42
+ type: 'object',
43
+ properties: {
44
+ refreshToken: { type: 'string' },
45
+ domain: { type: 'string' },
46
+ fingerprint: { type: 'string' },
47
+ label: { type: 'string' },
48
+ ...keepSessionProperty
49
+ },
50
+ additionalProperties: false
51
+ };
52
+ exports.logoutBodySchema = {
53
+ type: 'object',
54
+ properties: {
55
+ token: { type: 'string' },
56
+ refreshToken: { type: 'string' }
57
+ },
58
+ additionalProperties: false
59
+ };
60
+ exports.whoamiBodySchema = {
61
+ type: 'object',
62
+ properties: {
63
+ refreshToken: { type: 'string' },
64
+ refresh: { type: 'boolean' }
65
+ },
66
+ additionalProperties: false
67
+ };
68
+ /* ------------------------------------------------------------------ */
69
+ /* Passkey schemas */
70
+ /* ------------------------------------------------------------------ */
71
+ exports.passkeyChallengeBodySchema = {
72
+ type: 'object',
73
+ required: ['action'],
74
+ properties: {
75
+ action: { type: 'string', enum: ['register', 'authenticate'] },
76
+ login: { type: 'string' },
77
+ ...authIdentifierProperty('userId')
78
+ },
79
+ additionalProperties: false
80
+ };
81
+ exports.passkeyVerifyBodySchema = {
82
+ type: 'object',
83
+ required: ['expectedChallenge', 'response'],
84
+ properties: {
85
+ expectedChallenge: { type: 'string' },
86
+ response: { type: 'object' },
87
+ login: { type: 'string' },
88
+ ...authIdentifierProperty('userId'),
89
+ userAgent: { type: 'string' },
90
+ ...tokenMetadataProperties,
91
+ ...keepSessionProperty
92
+ },
93
+ additionalProperties: true
94
+ };
95
+ exports.passkeyCredentialParamsSchema = {
96
+ type: 'object',
97
+ required: ['credentialId'],
98
+ properties: {
99
+ credentialId: { type: 'string', minLength: 1 }
100
+ }
101
+ };
102
+ /* ------------------------------------------------------------------ */
103
+ /* Impersonation schemas */
104
+ /* ------------------------------------------------------------------ */
105
+ exports.impersonateBodySchema = {
106
+ type: 'object',
107
+ properties: {
108
+ ...authIdentifierProperty('userId'),
109
+ login: { type: 'string' },
110
+ ...tokenMetadataProperties,
111
+ ...keepSessionProperty,
112
+ clientId: { type: 'string' },
113
+ scope: {},
114
+ loginType: { type: 'string' }
115
+ },
116
+ additionalProperties: true
117
+ };
118
+ exports.deleteImpersonationQuerySchema = {
119
+ type: 'object',
120
+ additionalProperties: true
121
+ };
122
+ /* ------------------------------------------------------------------ */
123
+ /* OAuth schemas */
124
+ /* ------------------------------------------------------------------ */
125
+ exports.oauthProviderParamsSchema = {
126
+ type: 'object',
127
+ required: ['provider'],
128
+ properties: {
129
+ provider: { type: 'string', minLength: 1 }
130
+ }
131
+ };
132
+ exports.oauthStartBodySchema = {
133
+ type: 'object',
134
+ properties: {
135
+ redirectUri: { type: 'string' },
136
+ scope: {},
137
+ state: { type: 'string' },
138
+ extras: { type: 'object' }
139
+ },
140
+ additionalProperties: true
141
+ };
142
+ exports.oauthAuthorizeBodySchema = {
143
+ type: 'object',
144
+ required: ['clientId', 'redirectUri'],
145
+ properties: {
146
+ clientId: { type: 'string', minLength: 1 },
147
+ redirectUri: { type: 'string', minLength: 1 },
148
+ scope: {},
149
+ state: { type: 'string' },
150
+ codeChallenge: { type: 'string' },
151
+ codeChallengeMethod: { type: 'string' },
152
+ login: { type: 'string' },
153
+ password: { type: 'string' }
154
+ },
155
+ additionalProperties: false
156
+ };
157
+ exports.oauthTokenBodySchema = {
158
+ type: 'object',
159
+ required: ['grant_type'],
160
+ properties: {
161
+ grant_type: { type: 'string', enum: ['authorization_code', 'refresh_token'] },
162
+ code: { type: 'string' },
163
+ redirect_uri: { type: 'string' },
164
+ code_verifier: { type: 'string' },
165
+ client_id: { type: 'string' },
166
+ client_secret: { type: 'string' },
167
+ refresh_token: { type: 'string' },
168
+ scope: { type: 'string' }
169
+ },
170
+ additionalProperties: false
171
+ };
@@ -0,0 +1,21 @@
1
+ /**
2
+ * JSON Schema definitions for auth module routes.
3
+ * These are the runtime validation source-of-truth; TypeScript interfaces
4
+ * in auth-module.ts remain for handler-internal typing only.
5
+ */
6
+ /** Loose JSON Schema object type used for Fastify route schema definitions. */
7
+ type JsonSchema = Record<string, unknown>;
8
+ export declare const loginBodySchema: JsonSchema;
9
+ export declare const refreshBodySchema: JsonSchema;
10
+ export declare const logoutBodySchema: JsonSchema;
11
+ export declare const whoamiBodySchema: JsonSchema;
12
+ export declare const passkeyChallengeBodySchema: JsonSchema;
13
+ export declare const passkeyVerifyBodySchema: JsonSchema;
14
+ export declare const passkeyCredentialParamsSchema: JsonSchema;
15
+ export declare const impersonateBodySchema: JsonSchema;
16
+ export declare const deleteImpersonationQuerySchema: JsonSchema;
17
+ export declare const oauthProviderParamsSchema: JsonSchema;
18
+ export declare const oauthStartBodySchema: JsonSchema;
19
+ export declare const oauthAuthorizeBodySchema: JsonSchema;
20
+ export declare const oauthTokenBodySchema: JsonSchema;
21
+ export {};
@@ -0,0 +1,179 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SqlAuthStore = void 0;
4
+ const sequelize_js_1 = require("../oauth/sequelize.cjs");
5
+ const config_js_1 = require("../passkey/config.cjs");
6
+ const sequelize_js_2 = require("../passkey/sequelize.cjs");
7
+ const sequelize_utils_js_1 = require("../sequelize-utils.cjs");
8
+ const sequelize_js_3 = require("../token/sequelize.cjs");
9
+ const sequelize_js_4 = require("../user/sequelize.cjs");
10
+ const compat_auth_storage_js_1 = require("./compat-auth-storage.cjs");
11
+ const user_id_js_1 = require("./user-id.cjs");
12
+ function resolveTablePrefix(...prefixes) {
13
+ for (const prefix of prefixes) {
14
+ const normalized = (0, sequelize_utils_js_1.normalizeTablePrefix)(prefix);
15
+ if (normalized) {
16
+ return normalized;
17
+ }
18
+ }
19
+ return undefined;
20
+ }
21
+ class SqlAuthStore {
22
+ constructor(params) {
23
+ this.closed = false;
24
+ if (!params?.sequelize) {
25
+ throw new Error('SqlAuthStore requires an initialised Sequelize instance');
26
+ }
27
+ this.sequelize = params.sequelize;
28
+ this.syncOptions = params.syncOptions;
29
+ const moduleTablePrefixes = params.tablePrefixes ?? {};
30
+ const userTablePrefix = resolveTablePrefix(moduleTablePrefixes.user, params.tablePrefix);
31
+ this.userStore = new sequelize_js_4.SequelizeUserStore({
32
+ sequelize: this.sequelize,
33
+ userModel: params.userModel,
34
+ userModelFactory: params.userModelFactory,
35
+ recordMapper: params.userRecordMapper,
36
+ toPublic: params.publicUserMapper,
37
+ bcryptRounds: params.bcryptRounds,
38
+ bcryptPepper: params.passwordPepper,
39
+ tablePrefix: userTablePrefix
40
+ });
41
+ const tokenTablePrefix = resolveTablePrefix(params.tokenStoreOptions?.tablePrefix, moduleTablePrefixes.token, params.tablePrefix);
42
+ this.tokenStore =
43
+ params.tokenStore ??
44
+ new sequelize_js_3.SequelizeTokenStore({
45
+ sequelize: this.sequelize,
46
+ ...params.tokenStoreOptions,
47
+ tablePrefix: tokenTablePrefix
48
+ });
49
+ const oauthTablePrefix = resolveTablePrefix(params.oauthStoreOptions?.tablePrefix, moduleTablePrefixes.oauth, params.tablePrefix);
50
+ this.oauthStore = new sequelize_js_1.SequelizeOAuthStore({
51
+ sequelize: this.sequelize,
52
+ ...params.oauthStoreOptions,
53
+ tablePrefix: oauthTablePrefix,
54
+ bcryptRounds: params.bcryptRounds
55
+ });
56
+ let passkeyStore;
57
+ let passkeyConfig;
58
+ if (params.passkeys !== false) {
59
+ const passkeyTablePrefix = resolveTablePrefix(moduleTablePrefixes.passkey, params.tablePrefix);
60
+ passkeyConfig = (0, config_js_1.normalizePasskeyConfig)(params.passkeys ?? {});
61
+ const resolveUser = async (lookup) => {
62
+ const found = await this.userStore.findUser(lookup.userId ?? lookup.login ?? '');
63
+ if (!found) {
64
+ return null;
65
+ }
66
+ const mapper = params.passkeyUserMapper ??
67
+ ((user) => ({
68
+ id: (this.userStore.getUserId(user) ?? user['user_id']),
69
+ login: user.login ?? String(this.userStore.getUserId(user)),
70
+ displayName: user.login ?? String(this.userStore.getUserId(user))
71
+ }));
72
+ return mapper(found);
73
+ };
74
+ passkeyStore = new sequelize_js_2.SequelizePasskeyStore({
75
+ sequelize: this.sequelize,
76
+ resolveUser,
77
+ tablePrefix: passkeyTablePrefix
78
+ });
79
+ this.passkeyStore = passkeyStore;
80
+ }
81
+ this.adapter = new compat_auth_storage_js_1.CompositeAuthAdapter({
82
+ userStore: this.userStore,
83
+ tokenStore: this.tokenStore,
84
+ passkeys: passkeyStore && passkeyConfig ? { store: passkeyStore, config: passkeyConfig } : undefined,
85
+ oauthStore: this.oauthStore,
86
+ canImpersonate: params.canImpersonate
87
+ });
88
+ }
89
+ async initialise(withSync = false) {
90
+ await this.sequelize.authenticate();
91
+ if (withSync) {
92
+ await this.sequelize.sync(this.syncOptions);
93
+ }
94
+ }
95
+ async close() {
96
+ if (this.closed) {
97
+ return;
98
+ }
99
+ this.closed = true;
100
+ try {
101
+ await this.sequelize.close();
102
+ }
103
+ catch (error) {
104
+ const message = error?.message ?? '';
105
+ if (!/closed/i.test(message)) {
106
+ throw error;
107
+ }
108
+ }
109
+ finally {
110
+ // Prevent double-close errors when the same Sequelize instance is shared with other code.
111
+ this.sequelize.close = async () => { };
112
+ }
113
+ }
114
+ async getUser(identifier) {
115
+ return this.adapter.getUser(identifier);
116
+ }
117
+ getUserPasswordHash(user) {
118
+ return this.adapter.getUserPasswordHash(user);
119
+ }
120
+ getUserId(user) {
121
+ return this.adapter.getUserId(user);
122
+ }
123
+ filterUser(user) {
124
+ return this.adapter.filterUser(user);
125
+ }
126
+ async verifyPassword(password, hash) {
127
+ return this.adapter.verifyPassword(password, hash);
128
+ }
129
+ async storeToken(data) {
130
+ return this.adapter.storeToken(data);
131
+ }
132
+ async getToken(query, opts) {
133
+ const normalized = {
134
+ ...query,
135
+ userId: (0, user_id_js_1.toOptionalStringId)(query.userId),
136
+ ruid: (0, user_id_js_1.toOptionalStringId)(query.ruid)
137
+ };
138
+ return this.adapter.getToken(normalized, opts);
139
+ }
140
+ async deleteToken(query) {
141
+ const normalized = {
142
+ ...query,
143
+ userId: (0, user_id_js_1.toOptionalStringId)(query.userId),
144
+ ruid: (0, user_id_js_1.toOptionalStringId)(query.ruid)
145
+ };
146
+ return this.adapter.deleteToken(normalized);
147
+ }
148
+ async updateToken(updates) {
149
+ return this.adapter.updateToken(updates);
150
+ }
151
+ async createPasskeyChallenge(params) {
152
+ return this.adapter.createPasskeyChallenge(params);
153
+ }
154
+ async verifyPasskeyResponse(params) {
155
+ return this.adapter.verifyPasskeyResponse(params);
156
+ }
157
+ async listUserCredentials(userId) {
158
+ return this.adapter.listUserCredentials(userId);
159
+ }
160
+ async deletePasskeyCredential(credentialId) {
161
+ return this.adapter.deletePasskeyCredential(credentialId);
162
+ }
163
+ async getClient(clientId) {
164
+ return this.adapter.getClient(clientId);
165
+ }
166
+ async verifyClientSecret(client, clientSecret) {
167
+ return this.adapter.verifyClientSecret(client, clientSecret);
168
+ }
169
+ async createAuthCode(request) {
170
+ return this.adapter.createAuthCode(request);
171
+ }
172
+ async consumeAuthCode(code, clientId) {
173
+ return this.adapter.consumeAuthCode(code, clientId);
174
+ }
175
+ async canImpersonate(params) {
176
+ return this.adapter.canImpersonate(params);
177
+ }
178
+ }
179
+ exports.SqlAuthStore = SqlAuthStore;
@@ -0,0 +1,87 @@
1
+ import { Sequelize, type SyncOptions } from 'sequelize';
2
+ import { SequelizeOAuthStore, type SequelizeOAuthStoreOptions } from '../oauth/sequelize.js';
3
+ import { SequelizePasskeyStore } from '../passkey/sequelize.js';
4
+ import { type SequelizeTokenStoreOptions } from '../token/sequelize.js';
5
+ import { SequelizeUserStore, type AuthUserAttributes, GenericUserModel, GenericUserModelStatic } from '../user/sequelize.js';
6
+ import type { AuthAdapter, AuthIdentifier } from './types.js';
7
+ import type { AuthCodeData, AuthCodeRequest, OAuthClient } from '../oauth/types.js';
8
+ import type { PasskeyChallenge, PasskeyChallengeParams, PasskeyServiceConfig, PasskeyUserDescriptor, StoredPasskeyCredential, PasskeyVerificationParams, PasskeyVerificationResult } from '../passkey/types.js';
9
+ import type { TokenStore } from '../token/base.js';
10
+ import type { Token } from '../token/types.js';
11
+ interface PasskeyOptions extends Partial<PasskeyServiceConfig> {
12
+ enabled?: boolean;
13
+ }
14
+ export interface SqlAuthStoreTablePrefixes {
15
+ user?: string;
16
+ token?: string;
17
+ passkey?: string;
18
+ oauth?: string;
19
+ }
20
+ export interface SqlAuthStoreParams<UserAttributes extends AuthUserAttributes = AuthUserAttributes, PublicUserShape extends Omit<UserAttributes, 'password'> = Omit<UserAttributes, 'password'>> {
21
+ sequelize: Sequelize;
22
+ syncOptions?: SyncOptions;
23
+ bcryptRounds?: number;
24
+ passwordPepper?: string;
25
+ tablePrefix?: string;
26
+ tablePrefixes?: SqlAuthStoreTablePrefixes;
27
+ userModel?: GenericUserModelStatic;
28
+ userModelFactory?: (sequelize: Sequelize, options?: {
29
+ tablePrefix?: string;
30
+ }) => GenericUserModelStatic;
31
+ userRecordMapper?: (model: GenericUserModel) => UserAttributes;
32
+ publicUserMapper?: (user: UserAttributes) => PublicUserShape;
33
+ passkeyUserMapper?: (user: UserAttributes) => PasskeyUserDescriptor;
34
+ passkeys?: false | PasskeyOptions;
35
+ canImpersonate?: (params: {
36
+ realUserId: AuthIdentifier;
37
+ effectiveUserId: AuthIdentifier;
38
+ }) => boolean | Promise<boolean>;
39
+ tokenStore?: TokenStore;
40
+ tokenStoreOptions?: Omit<SequelizeTokenStoreOptions, 'sequelize'>;
41
+ oauthStoreOptions?: Omit<SequelizeOAuthStoreOptions, 'sequelize'>;
42
+ }
43
+ export declare class SqlAuthStore<UserAttributes extends AuthUserAttributes = AuthUserAttributes, PublicUserShape extends Omit<UserAttributes, 'password'> = Omit<UserAttributes, 'password'>> implements AuthAdapter<UserAttributes, PublicUserShape> {
44
+ readonly userStore: SequelizeUserStore<UserAttributes, PublicUserShape>;
45
+ readonly tokenStore: TokenStore;
46
+ readonly passkeyStore?: SequelizePasskeyStore;
47
+ readonly oauthStore: SequelizeOAuthStore;
48
+ private readonly adapter;
49
+ private readonly sequelize;
50
+ private closed;
51
+ private readonly syncOptions?;
52
+ constructor(params: SqlAuthStoreParams<UserAttributes, PublicUserShape>);
53
+ initialise(withSync?: boolean): Promise<void>;
54
+ close(): Promise<void>;
55
+ getUser(identifier: AuthIdentifier): Promise<UserAttributes | null>;
56
+ getUserPasswordHash(user: UserAttributes): string;
57
+ getUserId(user: UserAttributes): AuthIdentifier;
58
+ filterUser(user: UserAttributes): PublicUserShape;
59
+ verifyPassword(password: string, hash: string): Promise<boolean>;
60
+ storeToken(data: Token): Promise<void>;
61
+ getToken(query: Partial<Token> & {
62
+ userId?: AuthIdentifier;
63
+ ruid?: AuthIdentifier;
64
+ }, opts?: {
65
+ includeExpired?: boolean;
66
+ }): Promise<Token | null>;
67
+ deleteToken(query: Partial<Token> & {
68
+ userId?: AuthIdentifier;
69
+ ruid?: AuthIdentifier;
70
+ }): Promise<number>;
71
+ updateToken(updates: Partial<Token> & {
72
+ refreshToken: string;
73
+ }): Promise<boolean>;
74
+ createPasskeyChallenge(params: PasskeyChallengeParams): Promise<PasskeyChallenge>;
75
+ verifyPasskeyResponse(params: PasskeyVerificationParams): Promise<PasskeyVerificationResult>;
76
+ listUserCredentials(userId: AuthIdentifier): Promise<StoredPasskeyCredential[]>;
77
+ deletePasskeyCredential(credentialId: Buffer | string): Promise<boolean>;
78
+ getClient(clientId: string): Promise<OAuthClient | null>;
79
+ verifyClientSecret(client: OAuthClient, clientSecret: string | null): Promise<boolean>;
80
+ createAuthCode(request: AuthCodeRequest): Promise<AuthCodeData>;
81
+ consumeAuthCode(code: string, clientId: string): Promise<AuthCodeData | null>;
82
+ canImpersonate(params: {
83
+ realUserId: AuthIdentifier;
84
+ effectiveUserId: AuthIdentifier;
85
+ }): Promise<boolean>;
86
+ }
87
+ export {};
@@ -0,0 +1,102 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.nullAuthAdapter = exports.BaseAuthAdapter = void 0;
4
+ // Handy base you can extend when wiring a real auth adapter. Every method
5
+ // throws by default so unimplemented hooks fail loudly.
6
+ class BaseAuthAdapter {
7
+ // Override to load a user record by identifier
8
+ async getUser(identifier) {
9
+ void identifier;
10
+ return null;
11
+ }
12
+ // Override to return the stored password hash for the user
13
+ getUserPasswordHash(user) {
14
+ void user;
15
+ throw new Error('Auth storage not configured');
16
+ }
17
+ // Override to expose the canonical user identifier
18
+ getUserId(user) {
19
+ void user;
20
+ throw new Error('Auth storage not configured');
21
+ }
22
+ // Override to strip sensitive fields from the user record
23
+ filterUser(user) {
24
+ return user;
25
+ }
26
+ // Override to validate a raw password against the stored hash
27
+ async verifyPassword(password, hash) {
28
+ void password;
29
+ void hash;
30
+ throw new Error('Auth storage not configured');
31
+ }
32
+ // Override to persist newly issued tokens
33
+ async storeToken(data) {
34
+ void data;
35
+ throw new Error('Auth storage not configured');
36
+ }
37
+ // Override to look up a stored token by query
38
+ async getToken(query, opts) {
39
+ void query;
40
+ void opts;
41
+ return null;
42
+ }
43
+ // Override to remove stored tokens that match the query
44
+ async deleteToken(query) {
45
+ void query;
46
+ return 0;
47
+ }
48
+ // Override to update metadata for an existing refresh token
49
+ async updateToken(updates) {
50
+ void updates;
51
+ return false;
52
+ }
53
+ // Override to create a new passkey challenge record
54
+ async createPasskeyChallenge(params) {
55
+ void params;
56
+ throw new Error('Auth storage not configured');
57
+ }
58
+ // Override to verify an incoming WebAuthn response
59
+ async verifyPasskeyResponse(params) {
60
+ void params;
61
+ throw new Error('Auth storage not configured');
62
+ }
63
+ // Override to list passkey credentials for a user
64
+ async listUserCredentials(userId) {
65
+ void userId;
66
+ throw new Error('Auth storage not configured');
67
+ }
68
+ // Override to delete a passkey credential
69
+ async deletePasskeyCredential(credentialId) {
70
+ void credentialId;
71
+ throw new Error('Auth storage not configured');
72
+ }
73
+ // Override to fetch an OAuth client by identifier
74
+ async getClient(clientId) {
75
+ void clientId;
76
+ return null;
77
+ }
78
+ // Override to compare a provided client secret against storage
79
+ async verifyClientSecret(client, clientSecret) {
80
+ void client;
81
+ void clientSecret;
82
+ throw new Error('Auth storage not configured');
83
+ }
84
+ // Override to create a new authorization code entry
85
+ async createAuthCode(request) {
86
+ void request;
87
+ throw new Error('Auth storage not configured');
88
+ }
89
+ // Override to consume and invalidate an authorization code
90
+ async consumeAuthCode(code, clientId) {
91
+ void code;
92
+ void clientId;
93
+ return null;
94
+ }
95
+ // Override to decide if a real user may impersonate another user
96
+ async canImpersonate(params) {
97
+ void params;
98
+ return false;
99
+ }
100
+ }
101
+ exports.BaseAuthAdapter = BaseAuthAdapter;
102
+ exports.nullAuthAdapter = new BaseAuthAdapter();
@@ -0,0 +1,38 @@
1
+ import type { AuthAdapter, AuthIdentifier } from './types.js';
2
+ import type { AuthCodeData, AuthCodeRequest, OAuthClient } from '../oauth/types.js';
3
+ import type { PasskeyChallenge, PasskeyChallengeParams, PasskeyVerificationParams, PasskeyVerificationResult, StoredPasskeyCredential } from '../passkey/types.js';
4
+ import type { Token } from '../token/types.js';
5
+ export declare class BaseAuthAdapter<UserRow = unknown, SafeUser = unknown> implements AuthAdapter<UserRow, SafeUser> {
6
+ getUser(identifier: AuthIdentifier): Promise<UserRow | null>;
7
+ getUserPasswordHash(user: UserRow): string;
8
+ getUserId(user: UserRow): AuthIdentifier;
9
+ filterUser(user: UserRow): SafeUser;
10
+ verifyPassword(password: string, hash: string): Promise<boolean>;
11
+ storeToken(data: Token): Promise<void>;
12
+ getToken(query: Partial<Omit<Token, 'userId' | 'ruid'>> & {
13
+ userId?: string | number;
14
+ ruid?: string | number;
15
+ }, opts?: {
16
+ includeExpired?: boolean;
17
+ }): Promise<Token | null>;
18
+ deleteToken(query: Partial<Omit<Token, 'userId' | 'ruid'>> & {
19
+ userId?: string | number;
20
+ ruid?: string | number;
21
+ }): Promise<number>;
22
+ updateToken(updates: Partial<Token> & {
23
+ refreshToken: string;
24
+ }): Promise<boolean>;
25
+ createPasskeyChallenge(params: PasskeyChallengeParams): Promise<PasskeyChallenge>;
26
+ verifyPasskeyResponse(params: PasskeyVerificationParams): Promise<PasskeyVerificationResult>;
27
+ listUserCredentials(userId: AuthIdentifier): Promise<StoredPasskeyCredential[]>;
28
+ deletePasskeyCredential(credentialId: Buffer | string): Promise<boolean>;
29
+ getClient(clientId: string): Promise<OAuthClient | null>;
30
+ verifyClientSecret(client: OAuthClient, clientSecret: string | null): Promise<boolean>;
31
+ createAuthCode(request: AuthCodeRequest): Promise<AuthCodeData>;
32
+ consumeAuthCode(code: string, clientId: string): Promise<AuthCodeData | null>;
33
+ canImpersonate(params: {
34
+ realUserId: AuthIdentifier;
35
+ effectiveUserId: AuthIdentifier;
36
+ }): Promise<boolean>;
37
+ }
38
+ export declare const nullAuthAdapter: AuthAdapter<unknown, unknown>;
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,34 @@
1
+ import type { AuthCodeData, AuthCodeRequest, OAuthClient } from '../oauth/types.js';
2
+ import type { PasskeyChallenge, PasskeyChallengeParams, PasskeyVerificationParams, PasskeyVerificationResult, StoredPasskeyCredential } from '../passkey/types.js';
3
+ import type { Token } from '../token/types.js';
4
+ export type AuthIdentifier = string | number;
5
+ /** @internal */
6
+ export interface AuthAdapter<UserRow, SafeUser> {
7
+ getUser(identifier: AuthIdentifier): Promise<UserRow | null>;
8
+ getUserPasswordHash(user: UserRow): string;
9
+ getUserId(user: UserRow): AuthIdentifier;
10
+ filterUser(user: UserRow): SafeUser;
11
+ verifyPassword(password: string, hash: string): Promise<boolean>;
12
+ storeToken(data: Token): Promise<void>;
13
+ getToken(query: Partial<Token>, opts?: {
14
+ includeExpired?: boolean;
15
+ }): Promise<Token | null>;
16
+ deleteToken(query: Partial<Token>): Promise<number>;
17
+ updateToken?(updates: Partial<Token> & {
18
+ refreshToken: string;
19
+ }): Promise<boolean>;
20
+ createPasskeyChallenge?(params: PasskeyChallengeParams): Promise<PasskeyChallenge>;
21
+ verifyPasskeyResponse?(params: PasskeyVerificationParams): Promise<PasskeyVerificationResult>;
22
+ listUserCredentials?(userId: AuthIdentifier): Promise<StoredPasskeyCredential[]>;
23
+ deletePasskeyCredential?(credentialId: Buffer | string): Promise<boolean>;
24
+ getClient?(clientId: string): Promise<OAuthClient | null>;
25
+ verifyClientSecret?(client: OAuthClient, clientSecret: string | null): Promise<boolean>;
26
+ createAuthCode?(request: AuthCodeRequest): Promise<AuthCodeData>;
27
+ consumeAuthCode?(code: string, clientId: string): Promise<AuthCodeData | null>;
28
+ canImpersonate?(params: {
29
+ realUserId: AuthIdentifier;
30
+ effectiveUserId: AuthIdentifier;
31
+ }): Promise<boolean>;
32
+ }
33
+ /** @internal */
34
+ export type AuthStorage<UserRow, SafeUser> = AuthAdapter<UserRow, SafeUser>;