@fonoster/identity 0.27.0 → 0.31.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/README.md +25 -0
- package/dist/allowList.d.ts +4 -0
- package/dist/allowList.js +7 -1
- package/dist/apikeys/createCreateApiKey.js +16 -0
- package/dist/apikeys/createDeleteApiKey.js +22 -2
- package/dist/apikeys/createListApiKeys.js +14 -0
- package/dist/apikeys/createRegenerateApiKey.js +23 -2
- package/dist/config/index.d.ts +20 -0
- package/dist/config/index.js +36 -0
- package/dist/config/publishedKeys.d.ts +9 -0
- package/dist/config/publishedKeys.js +56 -0
- package/dist/config/schemas.d.ts +392 -0
- package/dist/config/schemas.js +163 -0
- package/dist/config/toIdentityConfig.d.ts +19 -0
- package/dist/config/toIdentityConfig.js +93 -0
- package/dist/constants.d.ts +28 -0
- package/dist/constants.js +29 -1
- package/dist/exchanges/createExchangeApiKey.js +4 -1
- package/dist/exchanges/createExchangeCredentials.d.ts +6 -1
- package/dist/exchanges/createExchangeCredentials.js +20 -2
- package/dist/exchanges/createExchangeOauth2Code.js +25 -2
- package/dist/exchanges/createExchangeRefreshToken.d.ts +9 -1
- package/dist/exchanges/createExchangeRefreshToken.js +57 -13
- package/dist/exchanges/createExchangeVerificationCode.d.ts +35 -0
- package/dist/exchanges/createExchangeVerificationCode.js +95 -0
- package/dist/exchanges/createRevokeToken.d.ts +33 -0
- package/dist/exchanges/createRevokeToken.js +64 -0
- package/dist/exchanges/exchangeTokens.d.ts +3 -1
- package/dist/exchanges/exchangeTokens.js +23 -5
- package/dist/exchanges/index.d.ts +2 -0
- package/dist/exchanges/index.js +2 -0
- package/dist/exchanges/payloads/users/createGetIdTokenPayload.js +3 -2
- package/dist/exchanges/refreshTokens.d.ts +30 -0
- package/dist/exchanges/refreshTokens.js +101 -0
- package/dist/exchanges/types.d.ts +53 -2
- package/dist/generated/@prisma/client/edge.js +27 -4
- package/dist/generated/@prisma/client/index-browser.js +24 -1
- package/dist/generated/@prisma/client/index.d.ts +3233 -417
- package/dist/generated/@prisma/client/index.js +31 -8
- package/dist/generated/@prisma/client/package.json +1 -1
- package/dist/generated/@prisma/client/runtime/edge-esm.js +2 -2
- package/dist/generated/@prisma/client/runtime/edge.js +2 -2
- package/dist/generated/@prisma/client/runtime/library.js +2 -2
- package/dist/generated/@prisma/client/runtime/react-native.js +2 -2
- package/dist/generated/@prisma/client/runtime/wasm-compiler-edge.js +2 -2
- package/dist/generated/@prisma/client/runtime/wasm-engine-edge.js +2 -2
- package/dist/generated/@prisma/client/schema.prisma +47 -7
- package/dist/generated/@prisma/client/wasm.js +27 -4
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/server/config.d.ts +286 -55
- package/dist/server/config.js +73 -108
- package/dist/server/index.js +5 -3
- package/dist/service.d.ts +6 -0
- package/dist/service.js +11 -4
- package/dist/users/createCreateUser.d.ts +6 -1
- package/dist/users/createCreateUser.js +17 -9
- package/dist/users/createCreateUserWithOauth2Code.js +19 -15
- package/dist/users/createResetPassword.d.ts +5 -0
- package/dist/users/createResetPassword.js +33 -7
- package/dist/users/createSendResetPasswordCode.d.ts +6 -0
- package/dist/users/createSendResetPasswordCode.js +33 -1
- package/dist/users/createUpdateUser.d.ts +7 -0
- package/dist/users/createUpdateUser.js +41 -8
- package/dist/users/createUserFromGitHub.d.ts +40 -0
- package/dist/users/createUserFromGitHub.js +27 -0
- package/dist/users/index.d.ts +1 -0
- package/dist/users/index.js +1 -0
- package/dist/users/migratePasswordStorage.d.ts +7 -0
- package/dist/users/migratePasswordStorage.js +47 -0
- package/dist/users/types.d.ts +3 -1
- package/dist/users/upsertDefaultUser.js +6 -14
- package/dist/utils/authMethods.d.ts +31 -0
- package/dist/utils/authMethods.js +44 -0
- package/dist/utils/claimUnverifiedAccount.d.ts +35 -0
- package/dist/utils/claimUnverifiedAccount.js +43 -0
- package/dist/utils/clientAddress.d.ts +26 -0
- package/dist/utils/clientAddress.js +9 -0
- package/dist/utils/createGenerateVerificationCode.d.ts +4 -0
- package/dist/utils/createGenerateVerificationCode.js +12 -2
- package/dist/utils/createGenerateWorkspaceInviteToken.js +3 -0
- package/dist/utils/createGetApiKeyByAccessKeyId.d.ts +5 -1
- package/dist/utils/createGetApiKeyByAccessKeyId.js +5 -0
- package/dist/utils/createGetUserByAccessKeyId.d.ts +3 -1
- package/dist/utils/createGetUserByEmail.d.ts +3 -1
- package/dist/utils/createGetUserByGitHubEmails.d.ts +41 -0
- package/dist/utils/createGetUserByGitHubEmails.js +31 -0
- package/dist/utils/createGetUserByWorkspaceAccessKeyId.d.ts +3 -1
- package/dist/utils/createIsValidVerificationCode.d.ts +5 -0
- package/dist/utils/createIsValidVerificationCode.js +34 -7
- package/dist/utils/createSendEmail.d.ts +2 -1
- package/dist/utils/createSendEmail.js +17 -0
- package/dist/utils/createUpdateMembershipStatus.js +10 -3
- package/dist/utils/generateOneTimePassword.d.ts +3 -0
- package/dist/utils/generateOneTimePassword.js +25 -0
- package/dist/utils/getGitHubUserWithOauth2Code.d.ts +20 -2
- package/dist/utils/getGitHubUserWithOauth2Code.js +41 -9
- package/dist/utils/hasAccessToResource.js +4 -5
- package/dist/utils/isWorkspaceAdminCall.d.ts +8 -0
- package/dist/utils/isWorkspaceAdminCall.js +47 -0
- package/dist/utils/normalizeContact.d.ts +22 -0
- package/dist/utils/normalizeContact.js +28 -0
- package/dist/utils/passwords.d.ts +11 -0
- package/dist/utils/passwords.js +84 -0
- package/dist/utils/rateLimiter.d.ts +20 -0
- package/dist/utils/rateLimiter.js +108 -0
- package/dist/utils/signInThrottle.d.ts +47 -0
- package/dist/utils/signInThrottle.js +90 -0
- package/dist/utils/userPasswords.d.ts +25 -0
- package/dist/utils/userPasswords.js +98 -0
- package/dist/utils/withAccess.js +3 -2
- package/dist/verification/createSendVerificationCode.js +27 -1
- package/dist/verification/createVerifyCode.js +10 -0
- package/dist/workspaces/createCreateWorkspace.d.ts +7 -1
- package/dist/workspaces/createCreateWorkspace.js +41 -5
- package/dist/workspaces/createDeleteWorkspace.d.ts +2 -1
- package/dist/workspaces/createDeleteWorkspace.js +16 -2
- package/dist/workspaces/createInviteUserToWorkspace.js +19 -17
- package/dist/workspaces/createResendWorkspaceMembershipInvitation.js +17 -2
- package/dist/workspaces/createUpdateWorkspace.js +18 -4
- package/dist/workspaces/createWorkspaceDirectory.d.ts +29 -0
- package/dist/workspaces/createWorkspaceDirectory.js +42 -0
- package/dist/workspaces/index.d.ts +1 -0
- package/dist/workspaces/index.js +1 -0
- package/package.json +11 -8
- package/dist/generated/@prisma/client/libquery_engine-darwin-arm64.dylib.node +0 -0
- package/dist/generated/@prisma/client/runtime/wasm.js +0 -35
|
@@ -0,0 +1,392 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (C) 2025 by Fonoster Inc (https://fonoster.com)
|
|
3
|
+
* http://github.com/fonoster/fonoster
|
|
4
|
+
*
|
|
5
|
+
* This file is part of Fonoster
|
|
6
|
+
*
|
|
7
|
+
* Licensed under the MIT License (the "License");
|
|
8
|
+
* you may not use this file except in compliance with
|
|
9
|
+
* the License. You may obtain a copy of the License at
|
|
10
|
+
*
|
|
11
|
+
* https://opensource.org/licenses/MIT
|
|
12
|
+
*
|
|
13
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
14
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
15
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
16
|
+
* See the License for the specific language governing permissions and
|
|
17
|
+
* limitations under the License.
|
|
18
|
+
*/
|
|
19
|
+
import { z } from "zod";
|
|
20
|
+
/** RS256 keys, inline or by path. Paths default to the container mount. */
|
|
21
|
+
declare const keysSchema: z.ZodEffects<z.ZodDefault<z.ZodObject<{
|
|
22
|
+
privateKey: z.ZodOptional<z.ZodString>;
|
|
23
|
+
publicKey: z.ZodOptional<z.ZodString>;
|
|
24
|
+
privateKeyPath: z.ZodOptional<z.ZodString>;
|
|
25
|
+
publicKeyPath: z.ZodOptional<z.ZodString>;
|
|
26
|
+
}, "strip", z.ZodTypeAny, {
|
|
27
|
+
privateKey?: string;
|
|
28
|
+
publicKey?: string;
|
|
29
|
+
privateKeyPath?: string;
|
|
30
|
+
publicKeyPath?: string;
|
|
31
|
+
}, {
|
|
32
|
+
privateKey?: string;
|
|
33
|
+
publicKey?: string;
|
|
34
|
+
privateKeyPath?: string;
|
|
35
|
+
publicKeyPath?: string;
|
|
36
|
+
}>>, {
|
|
37
|
+
privateKey: string;
|
|
38
|
+
publicKey: string;
|
|
39
|
+
privateKeyPath: string;
|
|
40
|
+
publicKeyPath: string;
|
|
41
|
+
}, {
|
|
42
|
+
privateKey?: string;
|
|
43
|
+
publicKey?: string;
|
|
44
|
+
privateKeyPath?: string;
|
|
45
|
+
publicKeyPath?: string;
|
|
46
|
+
}>;
|
|
47
|
+
declare const encryptionKeySchema: z.ZodString;
|
|
48
|
+
/** Outgoing email. Optional: without it, anything that sends email fails clearly. */
|
|
49
|
+
declare const smtpSchema: z.ZodObject<{
|
|
50
|
+
host: z.ZodString;
|
|
51
|
+
port: z.ZodDefault<z.ZodNumber>;
|
|
52
|
+
secure: z.ZodDefault<z.ZodBoolean>;
|
|
53
|
+
sender: z.ZodString;
|
|
54
|
+
user: z.ZodDefault<z.ZodString>;
|
|
55
|
+
password: z.ZodDefault<z.ZodString>;
|
|
56
|
+
}, "strip", z.ZodTypeAny, {
|
|
57
|
+
user?: string;
|
|
58
|
+
password?: string;
|
|
59
|
+
host?: string;
|
|
60
|
+
port?: number;
|
|
61
|
+
secure?: boolean;
|
|
62
|
+
sender?: string;
|
|
63
|
+
}, {
|
|
64
|
+
user?: string;
|
|
65
|
+
password?: string;
|
|
66
|
+
host?: string;
|
|
67
|
+
port?: number;
|
|
68
|
+
secure?: boolean;
|
|
69
|
+
sender?: string;
|
|
70
|
+
}>;
|
|
71
|
+
/** SMS for phone verification. */
|
|
72
|
+
declare const twilioSchema: z.ZodObject<{
|
|
73
|
+
phoneNumber: z.ZodString;
|
|
74
|
+
accountSid: z.ZodString;
|
|
75
|
+
authToken: z.ZodString;
|
|
76
|
+
}, "strip", z.ZodTypeAny, {
|
|
77
|
+
phoneNumber?: string;
|
|
78
|
+
accountSid?: string;
|
|
79
|
+
authToken?: string;
|
|
80
|
+
}, {
|
|
81
|
+
phoneNumber?: string;
|
|
82
|
+
accountSid?: string;
|
|
83
|
+
authToken?: string;
|
|
84
|
+
}>;
|
|
85
|
+
/** How people sign in and who may create an account. Community defaults. */
|
|
86
|
+
declare const authFeaturesSchema: z.ZodDefault<z.ZodObject<{
|
|
87
|
+
methods: z.ZodDefault<z.ZodArray<z.ZodEnum<["password", "email_code", "github"]>, "atleastone">>;
|
|
88
|
+
signup: z.ZodDefault<z.ZodEnum<["invite", "open"]>>;
|
|
89
|
+
}, "strip", z.ZodTypeAny, {
|
|
90
|
+
methods?: ["password" | "email_code" | "github", ...("password" | "email_code" | "github")[]];
|
|
91
|
+
signup?: "invite" | "open";
|
|
92
|
+
}, {
|
|
93
|
+
methods?: ["password" | "email_code" | "github", ...("password" | "email_code" | "github")[]];
|
|
94
|
+
signup?: "invite" | "open";
|
|
95
|
+
}>>;
|
|
96
|
+
declare const tokensSchema: z.ZodDefault<z.ZodObject<{
|
|
97
|
+
accessTokenExpiresIn: z.ZodDefault<z.ZodString>;
|
|
98
|
+
idTokenExpiresIn: z.ZodDefault<z.ZodString>;
|
|
99
|
+
refreshTokenExpiresIn: z.ZodDefault<z.ZodString>;
|
|
100
|
+
}, "strip", z.ZodTypeAny, {
|
|
101
|
+
accessTokenExpiresIn?: string;
|
|
102
|
+
idTokenExpiresIn?: string;
|
|
103
|
+
refreshTokenExpiresIn?: string;
|
|
104
|
+
}, {
|
|
105
|
+
accessTokenExpiresIn?: string;
|
|
106
|
+
idTokenExpiresIn?: string;
|
|
107
|
+
refreshTokenExpiresIn?: string;
|
|
108
|
+
}>>;
|
|
109
|
+
declare const securitySchema: z.ZodDefault<z.ZodObject<{
|
|
110
|
+
contactVerificationRequired: z.ZodDefault<z.ZodBoolean>;
|
|
111
|
+
twoFactorAuthenticationRequired: z.ZodDefault<z.ZodBoolean>;
|
|
112
|
+
}, "strip", z.ZodTypeAny, {
|
|
113
|
+
contactVerificationRequired?: boolean;
|
|
114
|
+
twoFactorAuthenticationRequired?: boolean;
|
|
115
|
+
}, {
|
|
116
|
+
contactVerificationRequired?: boolean;
|
|
117
|
+
twoFactorAuthenticationRequired?: boolean;
|
|
118
|
+
}>>;
|
|
119
|
+
declare const invitesSchema: z.ZodDefault<z.ZodObject<{
|
|
120
|
+
/** Defaults to <appUrl>/invites. */
|
|
121
|
+
url: z.ZodOptional<z.ZodString>;
|
|
122
|
+
/** Defaults to <appUrl>/invites/failed. */
|
|
123
|
+
failUrl: z.ZodOptional<z.ZodString>;
|
|
124
|
+
expiration: z.ZodDefault<z.ZodString>;
|
|
125
|
+
}, "strip", z.ZodTypeAny, {
|
|
126
|
+
url?: string;
|
|
127
|
+
failUrl?: string;
|
|
128
|
+
expiration?: string;
|
|
129
|
+
}, {
|
|
130
|
+
url?: string;
|
|
131
|
+
failUrl?: string;
|
|
132
|
+
expiration?: string;
|
|
133
|
+
}>>;
|
|
134
|
+
declare const oauth2Schema: z.ZodOptional<z.ZodObject<{
|
|
135
|
+
github: z.ZodObject<{
|
|
136
|
+
clientId: z.ZodString;
|
|
137
|
+
clientSecret: z.ZodString;
|
|
138
|
+
/** Where users authorize and codes are exchanged. Change only for tests (a fake GitHub). */
|
|
139
|
+
url: z.ZodEffects<z.ZodDefault<z.ZodString>, string, string>;
|
|
140
|
+
/** GitHub's REST API, for the user and their emails. */
|
|
141
|
+
apiUrl: z.ZodEffects<z.ZodDefault<z.ZodString>, string, string>;
|
|
142
|
+
}, "strip", z.ZodTypeAny, {
|
|
143
|
+
url?: string;
|
|
144
|
+
clientId?: string;
|
|
145
|
+
clientSecret?: string;
|
|
146
|
+
apiUrl?: string;
|
|
147
|
+
}, {
|
|
148
|
+
url?: string;
|
|
149
|
+
clientId?: string;
|
|
150
|
+
clientSecret?: string;
|
|
151
|
+
apiUrl?: string;
|
|
152
|
+
}>;
|
|
153
|
+
}, "strip", z.ZodTypeAny, {
|
|
154
|
+
github?: {
|
|
155
|
+
url?: string;
|
|
156
|
+
clientId?: string;
|
|
157
|
+
clientSecret?: string;
|
|
158
|
+
apiUrl?: string;
|
|
159
|
+
};
|
|
160
|
+
}, {
|
|
161
|
+
github?: {
|
|
162
|
+
url?: string;
|
|
163
|
+
clientId?: string;
|
|
164
|
+
clientSecret?: string;
|
|
165
|
+
apiUrl?: string;
|
|
166
|
+
};
|
|
167
|
+
}>>;
|
|
168
|
+
/** First admin, created on first boot. */
|
|
169
|
+
declare const ownerSchema: z.ZodOptional<z.ZodObject<{
|
|
170
|
+
name: z.ZodDefault<z.ZodString>;
|
|
171
|
+
email: z.ZodString;
|
|
172
|
+
password: z.ZodString;
|
|
173
|
+
}, "strip", z.ZodTypeAny, {
|
|
174
|
+
name?: string;
|
|
175
|
+
email?: string;
|
|
176
|
+
password?: string;
|
|
177
|
+
}, {
|
|
178
|
+
name?: string;
|
|
179
|
+
email?: string;
|
|
180
|
+
password?: string;
|
|
181
|
+
}>>;
|
|
182
|
+
/**
|
|
183
|
+
* fonoster.yaml's `identity:` section. Standalone Identity's identity.json has
|
|
184
|
+
* the same fields at its root (see server/config.ts).
|
|
185
|
+
*/
|
|
186
|
+
declare const identitySectionSchema: z.ZodDefault<z.ZodObject<{
|
|
187
|
+
/** Defaults to the top-level database. */
|
|
188
|
+
database: z.ZodOptional<z.ZodObject<{
|
|
189
|
+
url: z.ZodString;
|
|
190
|
+
}, "strip", z.ZodTypeAny, {
|
|
191
|
+
url?: string;
|
|
192
|
+
}, {
|
|
193
|
+
url?: string;
|
|
194
|
+
}>>;
|
|
195
|
+
/** Defaults to the app URL. */
|
|
196
|
+
issuer: z.ZodOptional<z.ZodString>;
|
|
197
|
+
audience: z.ZodDefault<z.ZodString>;
|
|
198
|
+
keys: z.ZodEffects<z.ZodDefault<z.ZodObject<{
|
|
199
|
+
privateKey: z.ZodOptional<z.ZodString>;
|
|
200
|
+
publicKey: z.ZodOptional<z.ZodString>;
|
|
201
|
+
privateKeyPath: z.ZodOptional<z.ZodString>;
|
|
202
|
+
publicKeyPath: z.ZodOptional<z.ZodString>;
|
|
203
|
+
}, "strip", z.ZodTypeAny, {
|
|
204
|
+
privateKey?: string;
|
|
205
|
+
publicKey?: string;
|
|
206
|
+
privateKeyPath?: string;
|
|
207
|
+
publicKeyPath?: string;
|
|
208
|
+
}, {
|
|
209
|
+
privateKey?: string;
|
|
210
|
+
publicKey?: string;
|
|
211
|
+
privateKeyPath?: string;
|
|
212
|
+
publicKeyPath?: string;
|
|
213
|
+
}>>, {
|
|
214
|
+
privateKey: string;
|
|
215
|
+
publicKey: string;
|
|
216
|
+
privateKeyPath: string;
|
|
217
|
+
publicKeyPath: string;
|
|
218
|
+
}, {
|
|
219
|
+
privateKey?: string;
|
|
220
|
+
publicKey?: string;
|
|
221
|
+
privateKeyPath?: string;
|
|
222
|
+
publicKeyPath?: string;
|
|
223
|
+
}>;
|
|
224
|
+
tokens: z.ZodDefault<z.ZodObject<{
|
|
225
|
+
accessTokenExpiresIn: z.ZodDefault<z.ZodString>;
|
|
226
|
+
idTokenExpiresIn: z.ZodDefault<z.ZodString>;
|
|
227
|
+
refreshTokenExpiresIn: z.ZodDefault<z.ZodString>;
|
|
228
|
+
}, "strip", z.ZodTypeAny, {
|
|
229
|
+
accessTokenExpiresIn?: string;
|
|
230
|
+
idTokenExpiresIn?: string;
|
|
231
|
+
refreshTokenExpiresIn?: string;
|
|
232
|
+
}, {
|
|
233
|
+
accessTokenExpiresIn?: string;
|
|
234
|
+
idTokenExpiresIn?: string;
|
|
235
|
+
refreshTokenExpiresIn?: string;
|
|
236
|
+
}>>;
|
|
237
|
+
security: z.ZodDefault<z.ZodObject<{
|
|
238
|
+
contactVerificationRequired: z.ZodDefault<z.ZodBoolean>;
|
|
239
|
+
twoFactorAuthenticationRequired: z.ZodDefault<z.ZodBoolean>;
|
|
240
|
+
}, "strip", z.ZodTypeAny, {
|
|
241
|
+
contactVerificationRequired?: boolean;
|
|
242
|
+
twoFactorAuthenticationRequired?: boolean;
|
|
243
|
+
}, {
|
|
244
|
+
contactVerificationRequired?: boolean;
|
|
245
|
+
twoFactorAuthenticationRequired?: boolean;
|
|
246
|
+
}>>;
|
|
247
|
+
invites: z.ZodDefault<z.ZodObject<{
|
|
248
|
+
/** Defaults to <appUrl>/invites. */
|
|
249
|
+
url: z.ZodOptional<z.ZodString>;
|
|
250
|
+
/** Defaults to <appUrl>/invites/failed. */
|
|
251
|
+
failUrl: z.ZodOptional<z.ZodString>;
|
|
252
|
+
expiration: z.ZodDefault<z.ZodString>;
|
|
253
|
+
}, "strip", z.ZodTypeAny, {
|
|
254
|
+
url?: string;
|
|
255
|
+
failUrl?: string;
|
|
256
|
+
expiration?: string;
|
|
257
|
+
}, {
|
|
258
|
+
url?: string;
|
|
259
|
+
failUrl?: string;
|
|
260
|
+
expiration?: string;
|
|
261
|
+
}>>;
|
|
262
|
+
oauth2: z.ZodOptional<z.ZodObject<{
|
|
263
|
+
github: z.ZodObject<{
|
|
264
|
+
clientId: z.ZodString;
|
|
265
|
+
clientSecret: z.ZodString;
|
|
266
|
+
/** Where users authorize and codes are exchanged. Change only for tests (a fake GitHub). */
|
|
267
|
+
url: z.ZodEffects<z.ZodDefault<z.ZodString>, string, string>;
|
|
268
|
+
/** GitHub's REST API, for the user and their emails. */
|
|
269
|
+
apiUrl: z.ZodEffects<z.ZodDefault<z.ZodString>, string, string>;
|
|
270
|
+
}, "strip", z.ZodTypeAny, {
|
|
271
|
+
url?: string;
|
|
272
|
+
clientId?: string;
|
|
273
|
+
clientSecret?: string;
|
|
274
|
+
apiUrl?: string;
|
|
275
|
+
}, {
|
|
276
|
+
url?: string;
|
|
277
|
+
clientId?: string;
|
|
278
|
+
clientSecret?: string;
|
|
279
|
+
apiUrl?: string;
|
|
280
|
+
}>;
|
|
281
|
+
}, "strip", z.ZodTypeAny, {
|
|
282
|
+
github?: {
|
|
283
|
+
url?: string;
|
|
284
|
+
clientId?: string;
|
|
285
|
+
clientSecret?: string;
|
|
286
|
+
apiUrl?: string;
|
|
287
|
+
};
|
|
288
|
+
}, {
|
|
289
|
+
github?: {
|
|
290
|
+
url?: string;
|
|
291
|
+
clientId?: string;
|
|
292
|
+
clientSecret?: string;
|
|
293
|
+
apiUrl?: string;
|
|
294
|
+
};
|
|
295
|
+
}>>;
|
|
296
|
+
owner: z.ZodOptional<z.ZodObject<{
|
|
297
|
+
name: z.ZodDefault<z.ZodString>;
|
|
298
|
+
email: z.ZodString;
|
|
299
|
+
password: z.ZodString;
|
|
300
|
+
}, "strip", z.ZodTypeAny, {
|
|
301
|
+
name?: string;
|
|
302
|
+
email?: string;
|
|
303
|
+
password?: string;
|
|
304
|
+
}, {
|
|
305
|
+
name?: string;
|
|
306
|
+
email?: string;
|
|
307
|
+
password?: string;
|
|
308
|
+
}>>;
|
|
309
|
+
}, "strip", z.ZodTypeAny, {
|
|
310
|
+
keys?: {
|
|
311
|
+
privateKey: string;
|
|
312
|
+
publicKey: string;
|
|
313
|
+
privateKeyPath: string;
|
|
314
|
+
publicKeyPath: string;
|
|
315
|
+
};
|
|
316
|
+
owner?: {
|
|
317
|
+
name?: string;
|
|
318
|
+
email?: string;
|
|
319
|
+
password?: string;
|
|
320
|
+
};
|
|
321
|
+
database?: {
|
|
322
|
+
url?: string;
|
|
323
|
+
};
|
|
324
|
+
issuer?: string;
|
|
325
|
+
audience?: string;
|
|
326
|
+
tokens?: {
|
|
327
|
+
accessTokenExpiresIn?: string;
|
|
328
|
+
idTokenExpiresIn?: string;
|
|
329
|
+
refreshTokenExpiresIn?: string;
|
|
330
|
+
};
|
|
331
|
+
security?: {
|
|
332
|
+
contactVerificationRequired?: boolean;
|
|
333
|
+
twoFactorAuthenticationRequired?: boolean;
|
|
334
|
+
};
|
|
335
|
+
invites?: {
|
|
336
|
+
url?: string;
|
|
337
|
+
failUrl?: string;
|
|
338
|
+
expiration?: string;
|
|
339
|
+
};
|
|
340
|
+
oauth2?: {
|
|
341
|
+
github?: {
|
|
342
|
+
url?: string;
|
|
343
|
+
clientId?: string;
|
|
344
|
+
clientSecret?: string;
|
|
345
|
+
apiUrl?: string;
|
|
346
|
+
};
|
|
347
|
+
};
|
|
348
|
+
}, {
|
|
349
|
+
keys?: {
|
|
350
|
+
privateKey?: string;
|
|
351
|
+
publicKey?: string;
|
|
352
|
+
privateKeyPath?: string;
|
|
353
|
+
publicKeyPath?: string;
|
|
354
|
+
};
|
|
355
|
+
owner?: {
|
|
356
|
+
name?: string;
|
|
357
|
+
email?: string;
|
|
358
|
+
password?: string;
|
|
359
|
+
};
|
|
360
|
+
database?: {
|
|
361
|
+
url?: string;
|
|
362
|
+
};
|
|
363
|
+
issuer?: string;
|
|
364
|
+
audience?: string;
|
|
365
|
+
tokens?: {
|
|
366
|
+
accessTokenExpiresIn?: string;
|
|
367
|
+
idTokenExpiresIn?: string;
|
|
368
|
+
refreshTokenExpiresIn?: string;
|
|
369
|
+
};
|
|
370
|
+
security?: {
|
|
371
|
+
contactVerificationRequired?: boolean;
|
|
372
|
+
twoFactorAuthenticationRequired?: boolean;
|
|
373
|
+
};
|
|
374
|
+
invites?: {
|
|
375
|
+
url?: string;
|
|
376
|
+
failUrl?: string;
|
|
377
|
+
expiration?: string;
|
|
378
|
+
};
|
|
379
|
+
oauth2?: {
|
|
380
|
+
github?: {
|
|
381
|
+
url?: string;
|
|
382
|
+
clientId?: string;
|
|
383
|
+
clientSecret?: string;
|
|
384
|
+
apiUrl?: string;
|
|
385
|
+
};
|
|
386
|
+
};
|
|
387
|
+
}>>;
|
|
388
|
+
type IdentitySection = z.infer<typeof identitySectionSchema>;
|
|
389
|
+
type SmtpConfigSection = z.infer<typeof smtpSchema>;
|
|
390
|
+
type TwilioConfigSection = z.infer<typeof twilioSchema>;
|
|
391
|
+
type AuthFeatures = z.infer<typeof authFeaturesSchema>;
|
|
392
|
+
export { authFeaturesSchema, encryptionKeySchema, invitesSchema, oauth2Schema, ownerSchema, securitySchema, tokensSchema, AuthFeatures, identitySectionSchema, IdentitySection, keysSchema, smtpSchema, SmtpConfigSection, twilioSchema, TwilioConfigSection };
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.twilioSchema = exports.smtpSchema = exports.keysSchema = exports.identitySectionSchema = exports.tokensSchema = exports.securitySchema = exports.ownerSchema = exports.oauth2Schema = exports.invitesSchema = exports.encryptionKeySchema = exports.authFeaturesSchema = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Copyright (C) 2025 by Fonoster Inc (https://fonoster.com)
|
|
6
|
+
* http://github.com/fonoster/fonoster
|
|
7
|
+
*
|
|
8
|
+
* This file is part of Fonoster
|
|
9
|
+
*
|
|
10
|
+
* Licensed under the MIT License (the "License");
|
|
11
|
+
* you may not use this file except in compliance with
|
|
12
|
+
* the License. You may obtain a copy of the License at
|
|
13
|
+
*
|
|
14
|
+
* https://opensource.org/licenses/MIT
|
|
15
|
+
*
|
|
16
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
17
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
18
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
19
|
+
* See the License for the specific language governing permissions and
|
|
20
|
+
* limitations under the License.
|
|
21
|
+
*/
|
|
22
|
+
const zod_1 = require("zod");
|
|
23
|
+
const DEFAULT_PRIVATE_KEY_PATH = "/opt/fonoster/keys/private.pem";
|
|
24
|
+
const DEFAULT_PUBLIC_KEY_PATH = "/opt/fonoster/keys/public.pem";
|
|
25
|
+
/** RS256 keys, inline or by path. Paths default to the container mount. */
|
|
26
|
+
const keysSchema = zod_1.z
|
|
27
|
+
.object({
|
|
28
|
+
privateKey: zod_1.z.string().optional(),
|
|
29
|
+
publicKey: zod_1.z.string().optional(),
|
|
30
|
+
privateKeyPath: zod_1.z.string().optional(),
|
|
31
|
+
publicKeyPath: zod_1.z.string().optional()
|
|
32
|
+
})
|
|
33
|
+
.default({})
|
|
34
|
+
.transform((keys) => {
|
|
35
|
+
var _a, _b;
|
|
36
|
+
return ({
|
|
37
|
+
privateKey: keys.privateKey,
|
|
38
|
+
publicKey: keys.publicKey,
|
|
39
|
+
privateKeyPath: keys.privateKey === undefined
|
|
40
|
+
? ((_a = keys.privateKeyPath) !== null && _a !== void 0 ? _a : DEFAULT_PRIVATE_KEY_PATH)
|
|
41
|
+
: undefined,
|
|
42
|
+
publicKeyPath: keys.publicKey === undefined
|
|
43
|
+
? ((_b = keys.publicKeyPath) !== null && _b !== void 0 ? _b : DEFAULT_PUBLIC_KEY_PATH)
|
|
44
|
+
: undefined
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
exports.keysSchema = keysSchema;
|
|
48
|
+
/**
|
|
49
|
+
* Key for the encrypted database fields (prisma-field-encryption / cloak):
|
|
50
|
+
* `k1.aesgcm256.<base64url of 32 bytes>`. Generate one with
|
|
51
|
+
* `npx @47ng/cloak generate`. The pattern is cloak's own `cloakKeyRegex`
|
|
52
|
+
* (@47ng/cloak 1.x): base64url (`-` and `_`, never `+` or `/`), 43 characters,
|
|
53
|
+
* optional `=` padding. A key that fails it would crash at startup with
|
|
54
|
+
* "Unknown key format", so it is rejected here instead.
|
|
55
|
+
*/
|
|
56
|
+
const CLOAK_KEY_REGEX = /^k1\.aesgcm256\.[A-Za-z0-9_-]{43}=?$/;
|
|
57
|
+
const encryptionKeySchema = zod_1.z.string().regex(CLOAK_KEY_REGEX, {
|
|
58
|
+
message: 'must look like "k1.aesgcm256.<43 base64url characters>" (A-Z a-z 0-9 - _, no + or /); generate one with `npx @47ng/cloak generate`'
|
|
59
|
+
});
|
|
60
|
+
exports.encryptionKeySchema = encryptionKeySchema;
|
|
61
|
+
/** Outgoing email. Optional: without it, anything that sends email fails clearly. */
|
|
62
|
+
const smtpSchema = zod_1.z.object({
|
|
63
|
+
host: zod_1.z.string().min(1),
|
|
64
|
+
port: zod_1.z.number().int().positive().default(587),
|
|
65
|
+
secure: zod_1.z.boolean().default(false),
|
|
66
|
+
sender: zod_1.z.string().min(1),
|
|
67
|
+
user: zod_1.z.string().default(""),
|
|
68
|
+
password: zod_1.z.string().default("")
|
|
69
|
+
});
|
|
70
|
+
exports.smtpSchema = smtpSchema;
|
|
71
|
+
/** SMS for phone verification. */
|
|
72
|
+
const twilioSchema = zod_1.z.object({
|
|
73
|
+
phoneNumber: zod_1.z.string().min(1),
|
|
74
|
+
accountSid: zod_1.z.string().min(1),
|
|
75
|
+
authToken: zod_1.z.string().min(1)
|
|
76
|
+
});
|
|
77
|
+
exports.twilioSchema = twilioSchema;
|
|
78
|
+
/** How people sign in and who may create an account. Community defaults. */
|
|
79
|
+
const authFeaturesSchema = zod_1.z
|
|
80
|
+
.object({
|
|
81
|
+
methods: zod_1.z
|
|
82
|
+
.array(zod_1.z.enum(["password", "email_code", "github"]))
|
|
83
|
+
.nonempty()
|
|
84
|
+
.default(["password"]),
|
|
85
|
+
signup: zod_1.z.enum(["invite", "open"]).default("invite")
|
|
86
|
+
})
|
|
87
|
+
.default({});
|
|
88
|
+
exports.authFeaturesSchema = authFeaturesSchema;
|
|
89
|
+
const tokensSchema = zod_1.z
|
|
90
|
+
.object({
|
|
91
|
+
accessTokenExpiresIn: zod_1.z.string().default("15m"),
|
|
92
|
+
idTokenExpiresIn: zod_1.z.string().default("15m"),
|
|
93
|
+
refreshTokenExpiresIn: zod_1.z.string().default("24h")
|
|
94
|
+
})
|
|
95
|
+
.default({});
|
|
96
|
+
exports.tokensSchema = tokensSchema;
|
|
97
|
+
const securitySchema = zod_1.z
|
|
98
|
+
.object({
|
|
99
|
+
contactVerificationRequired: zod_1.z.boolean().default(false),
|
|
100
|
+
twoFactorAuthenticationRequired: zod_1.z.boolean().default(false)
|
|
101
|
+
})
|
|
102
|
+
.default({});
|
|
103
|
+
exports.securitySchema = securitySchema;
|
|
104
|
+
const invitesSchema = zod_1.z
|
|
105
|
+
.object({
|
|
106
|
+
/** Defaults to <appUrl>/invites. */
|
|
107
|
+
url: zod_1.z.string().optional(),
|
|
108
|
+
/** Defaults to <appUrl>/invites/failed. */
|
|
109
|
+
failUrl: zod_1.z.string().optional(),
|
|
110
|
+
expiration: zod_1.z.string().default("1d")
|
|
111
|
+
})
|
|
112
|
+
.default({});
|
|
113
|
+
exports.invitesSchema = invitesSchema;
|
|
114
|
+
const oauth2Schema = zod_1.z
|
|
115
|
+
.object({
|
|
116
|
+
github: zod_1.z.object({
|
|
117
|
+
clientId: zod_1.z.string().min(1),
|
|
118
|
+
clientSecret: zod_1.z.string().min(1),
|
|
119
|
+
/** Where users authorize and codes are exchanged. Change only for tests (a fake GitHub). */
|
|
120
|
+
url: zod_1.z
|
|
121
|
+
.string()
|
|
122
|
+
.url()
|
|
123
|
+
.default("https://github.com")
|
|
124
|
+
.transform((v) => v.replace(/\/+$/, "")),
|
|
125
|
+
/** GitHub's REST API, for the user and their emails. */
|
|
126
|
+
apiUrl: zod_1.z
|
|
127
|
+
.string()
|
|
128
|
+
.url()
|
|
129
|
+
.default("https://api.github.com")
|
|
130
|
+
.transform((v) => v.replace(/\/+$/, ""))
|
|
131
|
+
})
|
|
132
|
+
})
|
|
133
|
+
.optional();
|
|
134
|
+
exports.oauth2Schema = oauth2Schema;
|
|
135
|
+
/** First admin, created on first boot. */
|
|
136
|
+
const ownerSchema = zod_1.z
|
|
137
|
+
.object({
|
|
138
|
+
name: zod_1.z.string().default("Admin"),
|
|
139
|
+
email: zod_1.z.string().email(),
|
|
140
|
+
password: zod_1.z.string().min(8)
|
|
141
|
+
})
|
|
142
|
+
.optional();
|
|
143
|
+
exports.ownerSchema = ownerSchema;
|
|
144
|
+
/**
|
|
145
|
+
* fonoster.yaml's `identity:` section. Standalone Identity's identity.json has
|
|
146
|
+
* the same fields at its root (see server/config.ts).
|
|
147
|
+
*/
|
|
148
|
+
const identitySectionSchema = zod_1.z
|
|
149
|
+
.object({
|
|
150
|
+
/** Defaults to the top-level database. */
|
|
151
|
+
database: zod_1.z.object({ url: zod_1.z.string().min(1) }).optional(),
|
|
152
|
+
/** Defaults to the app URL. */
|
|
153
|
+
issuer: zod_1.z.string().min(1).optional(),
|
|
154
|
+
audience: zod_1.z.string().min(1).default("api"),
|
|
155
|
+
keys: keysSchema,
|
|
156
|
+
tokens: tokensSchema,
|
|
157
|
+
security: securitySchema,
|
|
158
|
+
invites: invitesSchema,
|
|
159
|
+
oauth2: oauth2Schema,
|
|
160
|
+
owner: ownerSchema
|
|
161
|
+
})
|
|
162
|
+
.default({});
|
|
163
|
+
exports.identitySectionSchema = identitySectionSchema;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { IdentityConfig } from "../exchanges/types";
|
|
2
|
+
import { AuthFeatures, IdentitySection, SmtpConfigSection, TwilioConfigSection } from "./schemas";
|
|
3
|
+
type IdentityConfigInputs = {
|
|
4
|
+
identity: IdentitySection;
|
|
5
|
+
/** Public base URL, e.g. https://voice.acme.com. Used for issuer and invite links. */
|
|
6
|
+
appUrl: string;
|
|
7
|
+
/** Database used when identity.database is not set. */
|
|
8
|
+
databaseUrl: string;
|
|
9
|
+
encryptionKey: string;
|
|
10
|
+
smtp?: SmtpConfigSection;
|
|
11
|
+
twilio?: TwilioConfigSection;
|
|
12
|
+
auth?: AuthFeatures;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Builds the runtime IdentityConfig from validated config sections. Shared by
|
|
16
|
+
* the apiserver (fonoster.yaml) and standalone Identity (identity.json).
|
|
17
|
+
*/
|
|
18
|
+
declare function toIdentityConfig(inputs: IdentityConfigInputs): IdentityConfig;
|
|
19
|
+
export { toIdentityConfig, IdentityConfigInputs };
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.toIdentityConfig = toIdentityConfig;
|
|
4
|
+
/**
|
|
5
|
+
* Copyright (C) 2025 by Fonoster Inc (https://fonoster.com)
|
|
6
|
+
* http://github.com/fonoster/fonoster
|
|
7
|
+
*
|
|
8
|
+
* This file is part of Fonoster
|
|
9
|
+
*
|
|
10
|
+
* Licensed under the MIT License (the "License");
|
|
11
|
+
* you may not use this file except in compliance with
|
|
12
|
+
* the License. You may obtain a copy of the License at
|
|
13
|
+
*
|
|
14
|
+
* https://opensource.org/licenses/MIT
|
|
15
|
+
*
|
|
16
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
17
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
18
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
19
|
+
* See the License for the specific language governing permissions and
|
|
20
|
+
* limitations under the License.
|
|
21
|
+
*/
|
|
22
|
+
const fs_1 = require("fs");
|
|
23
|
+
const path_1 = require("path");
|
|
24
|
+
const publishedKeys_1 = require("./publishedKeys");
|
|
25
|
+
function readKey(inline, path) {
|
|
26
|
+
if (inline !== undefined) {
|
|
27
|
+
return inline;
|
|
28
|
+
}
|
|
29
|
+
const fullPath = (0, path_1.resolve)(process.cwd(), path);
|
|
30
|
+
try {
|
|
31
|
+
return (0, fs_1.readFileSync)(fullPath, "utf8");
|
|
32
|
+
}
|
|
33
|
+
catch (e) {
|
|
34
|
+
throw new Error(`unable to read identity key at ${fullPath}: ${e.message}`);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
const trimSlash = (url) => url.replace(/\/+$/, "");
|
|
38
|
+
/**
|
|
39
|
+
* Builds the runtime IdentityConfig from validated config sections. Shared by
|
|
40
|
+
* the apiserver (fonoster.yaml) and standalone Identity (identity.json).
|
|
41
|
+
*/
|
|
42
|
+
function toIdentityConfig(inputs) {
|
|
43
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
44
|
+
const { identity, smtp, twilio } = inputs;
|
|
45
|
+
const appUrl = trimSlash(inputs.appUrl);
|
|
46
|
+
const privateKey = readKey(identity.keys.privateKey, identity.keys.privateKeyPath);
|
|
47
|
+
const publicKey = readKey(identity.keys.publicKey, identity.keys.publicKeyPath);
|
|
48
|
+
(0, publishedKeys_1.assertUnpublishedKeys)({
|
|
49
|
+
privateKey,
|
|
50
|
+
publicKey,
|
|
51
|
+
encryptionKey: inputs.encryptionKey
|
|
52
|
+
});
|
|
53
|
+
return {
|
|
54
|
+
dbUrl: (_b = (_a = identity.database) === null || _a === void 0 ? void 0 : _a.url) !== null && _b !== void 0 ? _b : inputs.databaseUrl,
|
|
55
|
+
issuer: (_c = identity.issuer) !== null && _c !== void 0 ? _c : appUrl,
|
|
56
|
+
audience: identity.audience,
|
|
57
|
+
privateKey,
|
|
58
|
+
publicKey,
|
|
59
|
+
encryptionKey: inputs.encryptionKey,
|
|
60
|
+
accessTokenExpiresIn: identity.tokens.accessTokenExpiresIn,
|
|
61
|
+
refreshTokenExpiresIn: identity.tokens.refreshTokenExpiresIn,
|
|
62
|
+
idTokenExpiresIn: identity.tokens.idTokenExpiresIn,
|
|
63
|
+
workspaceInviteExpiration: identity.invites.expiration,
|
|
64
|
+
workspaceInviteUrl: (_d = identity.invites.url) !== null && _d !== void 0 ? _d : `${appUrl}/invites`,
|
|
65
|
+
workspaceInviteFailUrl: (_e = identity.invites.failUrl) !== null && _e !== void 0 ? _e : `${appUrl}/invites/failed`,
|
|
66
|
+
resetPasswordUrl: `${appUrl}/reset-password`,
|
|
67
|
+
contactVerificationRequired: identity.security.contactVerificationRequired,
|
|
68
|
+
twoFactorAuthenticationRequired: identity.security.twoFactorAuthenticationRequired,
|
|
69
|
+
smtpConfig: smtp
|
|
70
|
+
? {
|
|
71
|
+
host: smtp.host,
|
|
72
|
+
port: smtp.port,
|
|
73
|
+
secure: smtp.secure,
|
|
74
|
+
sender: smtp.sender,
|
|
75
|
+
auth: { user: smtp.user, pass: smtp.password }
|
|
76
|
+
}
|
|
77
|
+
: undefined,
|
|
78
|
+
twilioSmsConfig: twilio
|
|
79
|
+
? {
|
|
80
|
+
accountSid: twilio.accountSid,
|
|
81
|
+
authToken: twilio.authToken,
|
|
82
|
+
sender: twilio.phoneNumber
|
|
83
|
+
}
|
|
84
|
+
: undefined,
|
|
85
|
+
// Validated by the schema; casts only bridge zod's inference under this
|
|
86
|
+
// package's non-strict tsconfig.
|
|
87
|
+
githubOauth2Config: (_f = identity.oauth2) === null || _f === void 0 ? void 0 : _f.github,
|
|
88
|
+
auth: ((_g = inputs.auth) !== null && _g !== void 0 ? _g : {
|
|
89
|
+
methods: ["password"],
|
|
90
|
+
signup: "invite"
|
|
91
|
+
})
|
|
92
|
+
};
|
|
93
|
+
}
|
package/dist/constants.d.ts
CHANGED
|
@@ -18,3 +18,31 @@
|
|
|
18
18
|
*/
|
|
19
19
|
export declare const SIGN_ALGORITHM = "RS256";
|
|
20
20
|
export declare const VERIFICATION_CODE_EXPIRATION: number;
|
|
21
|
+
/** Wrong guesses allowed before a code stops working. */
|
|
22
|
+
export declare const VERIFICATION_CODE_MAX_ATTEMPTS = 5;
|
|
23
|
+
/** Codes sent per email, and per client IP, within the window. */
|
|
24
|
+
export declare const VERIFICATION_CODE_SEND_LIMITS: {
|
|
25
|
+
perEmail: number;
|
|
26
|
+
perIp: number;
|
|
27
|
+
windowMs: number;
|
|
28
|
+
};
|
|
29
|
+
/** ResetPassword attempts per email, and per client IP, within the window. */
|
|
30
|
+
export declare const RESET_PASSWORD_ATTEMPT_LIMITS: {
|
|
31
|
+
perEmail: number;
|
|
32
|
+
perIp: number;
|
|
33
|
+
windowMs: number;
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Failed sign-ins (ExchangeCredentials, ExchangeVerificationCode) per email,
|
|
37
|
+
* and per client IP, before sign-in is refused for the rest of the window.
|
|
38
|
+
*/
|
|
39
|
+
export declare const SIGN_IN_FAILURE_LIMITS: {
|
|
40
|
+
perEmail: number;
|
|
41
|
+
perIp: number;
|
|
42
|
+
windowMs: number;
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* How long a just-used refresh token may be used again (concurrent renewals,
|
|
46
|
+
* e.g. two browser tabs). Later reuse revokes the token's family.
|
|
47
|
+
*/
|
|
48
|
+
export declare const REFRESH_TOKEN_REUSE_GRACE_MS: number;
|