@factiii/auth 0.3.0 → 0.4.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 +5 -1
- package/dist/{chunk-PYVDWODF.mjs → chunk-EHI4P63M.mjs} +0 -21
- package/dist/{hooks-B41uikq7.d.mts → hooks-BXNxNK4S.d.mts} +1 -55
- package/dist/{hooks-B41uikq7.d.ts → hooks-BXNxNK4S.d.ts} +1 -55
- package/dist/index.d.mts +30 -51
- package/dist/index.d.ts +30 -51
- package/dist/index.js +93 -189
- package/dist/index.mjs +89 -169
- package/dist/validators.d.mts +1 -1
- package/dist/validators.d.ts +1 -1
- package/dist/validators.js +0 -26
- package/dist/validators.mjs +1 -11
- package/package.json +1 -1
- package/prisma/schema.prisma +17 -19
package/dist/index.js
CHANGED
|
@@ -35,12 +35,12 @@ __export(index_exports, {
|
|
|
35
35
|
biometricVerifySchema: () => biometricVerifySchema,
|
|
36
36
|
changePasswordSchema: () => changePasswordSchema,
|
|
37
37
|
cleanBase32String: () => cleanBase32String,
|
|
38
|
-
|
|
38
|
+
clearAuthCookie: () => clearAuthCookie,
|
|
39
39
|
comparePassword: () => comparePassword,
|
|
40
|
-
createAccessToken: () => createAccessToken,
|
|
41
40
|
createAuthConfig: () => createAuthConfig,
|
|
42
41
|
createAuthGuard: () => createAuthGuard,
|
|
43
42
|
createAuthRouter: () => createAuthRouter,
|
|
43
|
+
createAuthToken: () => createAuthToken,
|
|
44
44
|
createConsoleEmailAdapter: () => createConsoleEmailAdapter,
|
|
45
45
|
createNoopEmailAdapter: () => createNoopEmailAdapter,
|
|
46
46
|
createOAuthVerifier: () => createOAuthVerifier,
|
|
@@ -60,20 +60,16 @@ __export(index_exports, {
|
|
|
60
60
|
isTokenExpiredError: () => isTokenExpiredError,
|
|
61
61
|
isTokenInvalidError: () => isTokenInvalidError,
|
|
62
62
|
loginSchema: () => loginSchema,
|
|
63
|
-
logoutSchema: () => logoutSchema,
|
|
64
63
|
oAuthLoginSchema: () => oAuthLoginSchema,
|
|
65
|
-
|
|
66
|
-
otpLoginVerifySchema: () => otpLoginVerifySchema,
|
|
67
|
-
parseAuthCookies: () => parseAuthCookies,
|
|
64
|
+
parseAuthCookie: () => parseAuthCookie,
|
|
68
65
|
requestPasswordResetSchema: () => requestPasswordResetSchema,
|
|
69
66
|
resetPasswordSchema: () => resetPasswordSchema,
|
|
70
|
-
|
|
67
|
+
setAuthCookie: () => setAuthCookie,
|
|
71
68
|
signupSchema: () => signupSchema,
|
|
72
69
|
twoFaResetSchema: () => twoFaResetSchema,
|
|
73
|
-
twoFaSetupSchema: () => twoFaSetupSchema,
|
|
74
70
|
twoFaVerifySchema: () => twoFaVerifySchema,
|
|
75
71
|
validatePasswordStrength: () => validatePasswordStrength,
|
|
76
|
-
|
|
72
|
+
verifyAuthToken: () => verifyAuthToken,
|
|
77
73
|
verifyEmailSchema: () => verifyEmailSchema,
|
|
78
74
|
verifyTotp: () => verifyTotp
|
|
79
75
|
});
|
|
@@ -137,7 +133,8 @@ function createConsoleEmailAdapter() {
|
|
|
137
133
|
|
|
138
134
|
// src/utilities/config.ts
|
|
139
135
|
var defaultTokenSettings = {
|
|
140
|
-
|
|
136
|
+
jwtExpiry: 30 * 24 * 60 * 60,
|
|
137
|
+
// 30 days in seconds
|
|
141
138
|
passwordResetExpiryMs: 60 * 60 * 1e3,
|
|
142
139
|
// 1 hour
|
|
143
140
|
otpValidityMs: 15 * 60 * 1e3
|
|
@@ -146,15 +143,13 @@ var defaultTokenSettings = {
|
|
|
146
143
|
var defaultCookieSettings = {
|
|
147
144
|
secure: true,
|
|
148
145
|
sameSite: "Strict",
|
|
149
|
-
httpOnly:
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
// 1 year in seconds
|
|
146
|
+
httpOnly: false,
|
|
147
|
+
path: "/",
|
|
148
|
+
maxAge: 30 * 24 * 60 * 60
|
|
149
|
+
// 30 days in seconds
|
|
154
150
|
};
|
|
155
151
|
var defaultStorageKeys = {
|
|
156
|
-
|
|
157
|
-
refreshToken: "auth-rt"
|
|
152
|
+
authToken: "auth-token"
|
|
158
153
|
};
|
|
159
154
|
var defaultFeatures = {
|
|
160
155
|
twoFa: true,
|
|
@@ -186,21 +181,17 @@ var defaultAuthConfig = {
|
|
|
186
181
|
|
|
187
182
|
// src/utilities/cookies.ts
|
|
188
183
|
var DEFAULT_STORAGE_KEYS = {
|
|
189
|
-
|
|
190
|
-
REFRESH_TOKEN: "auth-rt"
|
|
184
|
+
AUTH_TOKEN: "auth-token"
|
|
191
185
|
};
|
|
192
|
-
function
|
|
193
|
-
|
|
194
|
-
refreshToken: DEFAULT_STORAGE_KEYS.REFRESH_TOKEN
|
|
186
|
+
function parseAuthCookie(cookieHeader, storageKeys = {
|
|
187
|
+
authToken: DEFAULT_STORAGE_KEYS.AUTH_TOKEN
|
|
195
188
|
}) {
|
|
196
189
|
if (!cookieHeader) {
|
|
197
190
|
return {};
|
|
198
191
|
}
|
|
199
|
-
const
|
|
200
|
-
const refreshToken = cookieHeader.split(`${storageKeys.refreshToken}=`)[1]?.split(";")[0];
|
|
192
|
+
const authToken = cookieHeader.split(`${storageKeys.authToken}=`)[1]?.split(";")[0];
|
|
201
193
|
return {
|
|
202
|
-
|
|
203
|
-
refreshToken: refreshToken || void 0
|
|
194
|
+
authToken: authToken || void 0
|
|
204
195
|
};
|
|
205
196
|
}
|
|
206
197
|
function extractDomain(req) {
|
|
@@ -224,76 +215,47 @@ function extractDomain(req) {
|
|
|
224
215
|
}
|
|
225
216
|
return void 0;
|
|
226
217
|
}
|
|
227
|
-
function
|
|
228
|
-
|
|
229
|
-
refreshToken: DEFAULT_STORAGE_KEYS.REFRESH_TOKEN
|
|
218
|
+
function setAuthCookie(res, authToken, settings, storageKeys = {
|
|
219
|
+
authToken: DEFAULT_STORAGE_KEYS.AUTH_TOKEN
|
|
230
220
|
}) {
|
|
231
|
-
const cookies = [];
|
|
232
221
|
const domain = settings.domain ?? extractDomain(res.req);
|
|
233
222
|
const expiresDate = settings.maxAge ? new Date(Date.now() + settings.maxAge * 1e3).toUTCString() : void 0;
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
cookies.push(refreshCookie);
|
|
245
|
-
}
|
|
246
|
-
if (credentials.accessToken) {
|
|
247
|
-
const accessCookie = [
|
|
248
|
-
`${storageKeys.accessToken}=${credentials.accessToken}`,
|
|
249
|
-
settings.secure ? "Secure=true" : "",
|
|
250
|
-
`SameSite=${settings.sameSite}`,
|
|
251
|
-
`Path=${settings.accessTokenPath}`,
|
|
252
|
-
domain ? `Domain=${domain}` : "",
|
|
253
|
-
`Expires=${expiresDate}`
|
|
254
|
-
].filter(Boolean).join("; ");
|
|
255
|
-
cookies.push(accessCookie);
|
|
256
|
-
}
|
|
257
|
-
if (cookies.length > 0) {
|
|
258
|
-
res.setHeader("Set-Cookie", cookies);
|
|
259
|
-
}
|
|
223
|
+
const cookie = [
|
|
224
|
+
`${storageKeys.authToken}=${authToken}`,
|
|
225
|
+
settings.httpOnly ? "HttpOnly" : "",
|
|
226
|
+
settings.secure ? "Secure=true" : "",
|
|
227
|
+
`SameSite=${settings.sameSite}`,
|
|
228
|
+
`Path=${settings.path ?? "/"}`,
|
|
229
|
+
domain ? `Domain=${domain}` : "",
|
|
230
|
+
expiresDate ? `Expires=${expiresDate}` : ""
|
|
231
|
+
].filter(Boolean).join("; ");
|
|
232
|
+
res.setHeader("Set-Cookie", cookie);
|
|
260
233
|
}
|
|
261
|
-
function
|
|
262
|
-
|
|
263
|
-
refreshToken: DEFAULT_STORAGE_KEYS.REFRESH_TOKEN
|
|
234
|
+
function clearAuthCookie(res, settings, storageKeys = {
|
|
235
|
+
authToken: DEFAULT_STORAGE_KEYS.AUTH_TOKEN
|
|
264
236
|
}) {
|
|
265
237
|
const domain = extractDomain(res.req);
|
|
266
238
|
const expiredDate = (/* @__PURE__ */ new Date(0)).toUTCString();
|
|
267
|
-
const
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
[
|
|
278
|
-
`${storageKeys.accessToken}=destroy`,
|
|
279
|
-
settings.secure ? "Secure=true" : "",
|
|
280
|
-
`SameSite=${settings.sameSite}`,
|
|
281
|
-
`Path=${settings.accessTokenPath}`,
|
|
282
|
-
domain ? `Domain=${domain}` : "",
|
|
283
|
-
`Expires=${expiredDate}`
|
|
284
|
-
].filter(Boolean).join("; ")
|
|
285
|
-
];
|
|
286
|
-
res.setHeader("Set-Cookie", cookies);
|
|
239
|
+
const cookie = [
|
|
240
|
+
`${storageKeys.authToken}=destroy`,
|
|
241
|
+
settings.httpOnly ? "HttpOnly" : "",
|
|
242
|
+
settings.secure ? "Secure=true" : "",
|
|
243
|
+
`SameSite=${settings.sameSite}`,
|
|
244
|
+
`Path=${settings.path ?? "/"}`,
|
|
245
|
+
domain ? `Domain=${domain}` : "",
|
|
246
|
+
`Expires=${expiredDate}`
|
|
247
|
+
].filter(Boolean).join("; ");
|
|
248
|
+
res.setHeader("Set-Cookie", cookie);
|
|
287
249
|
}
|
|
288
250
|
|
|
289
251
|
// src/utilities/jwt.ts
|
|
290
252
|
var import_jsonwebtoken = __toESM(require("jsonwebtoken"));
|
|
291
|
-
function
|
|
253
|
+
function createAuthToken(payload, options) {
|
|
292
254
|
return import_jsonwebtoken.default.sign(payload, options.secret, {
|
|
293
255
|
expiresIn: options.expiresIn
|
|
294
256
|
});
|
|
295
257
|
}
|
|
296
|
-
function
|
|
258
|
+
function verifyAuthToken(token, options) {
|
|
297
259
|
return import_jsonwebtoken.default.verify(token, options.secret, {
|
|
298
260
|
ignoreExpiration: options.ignoreExpiration ?? false
|
|
299
261
|
});
|
|
@@ -320,7 +282,7 @@ function createAuthGuard(config, t) {
|
|
|
320
282
|
const storageKeys = config.storageKeys ?? defaultStorageKeys;
|
|
321
283
|
const cookieSettings = { ...defaultCookieSettings, ...config.cookieSettings };
|
|
322
284
|
const revokeSession = async (ctx, sessionId, description, errorStack, path) => {
|
|
323
|
-
|
|
285
|
+
clearAuthCookie(ctx.res, cookieSettings, storageKeys);
|
|
324
286
|
if (config.hooks?.logError) {
|
|
325
287
|
try {
|
|
326
288
|
const cookieHeader = ctx.headers.cookie;
|
|
@@ -331,7 +293,6 @@ function createAuthGuard(config, t) {
|
|
|
331
293
|
ip: ctx.ip,
|
|
332
294
|
userAgent: ctx.headers["user-agent"],
|
|
333
295
|
...path ? { path } : {},
|
|
334
|
-
// Diagnostic: was Cookie header present at all, and which keys were sent?
|
|
335
296
|
hasCookieHeader: Boolean(cookieHeader),
|
|
336
297
|
cookieKeys: cookieHeader ? cookieHeader.split(";").map((c) => c.trim().split("=")[0]).filter(Boolean) : [],
|
|
337
298
|
origin: ctx.headers.origin ?? null,
|
|
@@ -374,9 +335,8 @@ ${errorStack}` : null,
|
|
|
374
335
|
}
|
|
375
336
|
};
|
|
376
337
|
const authGuard = t.middleware(async ({ ctx, meta, next, path }) => {
|
|
377
|
-
const cookies =
|
|
378
|
-
const authToken = cookies.
|
|
379
|
-
const refreshToken = cookies.refreshToken;
|
|
338
|
+
const cookies = parseAuthCookie(ctx.headers.cookie, storageKeys);
|
|
339
|
+
const authToken = cookies.authToken;
|
|
380
340
|
const userAgent = ctx.headers["user-agent"];
|
|
381
341
|
if (!userAgent) {
|
|
382
342
|
throw new import_server.TRPCError({
|
|
@@ -386,27 +346,13 @@ ${errorStack}` : null,
|
|
|
386
346
|
}
|
|
387
347
|
if (authToken) {
|
|
388
348
|
try {
|
|
389
|
-
const decodedToken =
|
|
349
|
+
const decodedToken = verifyAuthToken(authToken, {
|
|
390
350
|
secret: config.secrets.jwt,
|
|
391
351
|
ignoreExpiration: meta?.ignoreExpiration ?? false
|
|
392
352
|
});
|
|
393
|
-
if (path === "auth.refresh" && !refreshToken) {
|
|
394
|
-
await revokeSession(
|
|
395
|
-
ctx,
|
|
396
|
-
decodedToken.id,
|
|
397
|
-
"Session revoked: No refresh token",
|
|
398
|
-
void 0,
|
|
399
|
-
path
|
|
400
|
-
);
|
|
401
|
-
throw new import_server.TRPCError({
|
|
402
|
-
message: "Unauthorized",
|
|
403
|
-
code: "UNAUTHORIZED"
|
|
404
|
-
});
|
|
405
|
-
}
|
|
406
353
|
const session = await config.prisma.session.findUnique({
|
|
407
354
|
where: {
|
|
408
|
-
id: decodedToken.id
|
|
409
|
-
...path === "auth.refresh" ? { refreshToken } : {}
|
|
355
|
+
id: decodedToken.id
|
|
410
356
|
},
|
|
411
357
|
select: {
|
|
412
358
|
userId: true,
|
|
@@ -497,8 +443,7 @@ ${errorStack}` : null,
|
|
|
497
443
|
...ctx,
|
|
498
444
|
userId: session.userId,
|
|
499
445
|
socketId: session.socketId,
|
|
500
|
-
sessionId: session.id
|
|
501
|
-
refreshToken
|
|
446
|
+
sessionId: session.id
|
|
502
447
|
}
|
|
503
448
|
});
|
|
504
449
|
} catch (err) {
|
|
@@ -543,7 +488,6 @@ ${errorStack}` : null,
|
|
|
543
488
|
}
|
|
544
489
|
|
|
545
490
|
// src/procedures/base.ts
|
|
546
|
-
var import_node_crypto = require("crypto");
|
|
547
491
|
var import_server2 = require("@trpc/server");
|
|
548
492
|
|
|
549
493
|
// src/utilities/browser.ts
|
|
@@ -742,9 +686,6 @@ var twoFaVerifySchema = import_zod.z.object({
|
|
|
742
686
|
code: import_zod.z.string().min(6, { message: "Verification code is required" }),
|
|
743
687
|
sessionId: import_zod.z.number().optional()
|
|
744
688
|
});
|
|
745
|
-
var twoFaSetupSchema = import_zod.z.object({
|
|
746
|
-
code: import_zod.z.string().min(6, { message: "Verification code is required" })
|
|
747
|
-
});
|
|
748
689
|
var twoFaResetSchema = import_zod.z.object({
|
|
749
690
|
username: import_zod.z.string().min(1),
|
|
750
691
|
password: import_zod.z.string().min(1)
|
|
@@ -756,9 +697,6 @@ var twoFaResetVerifySchema = import_zod.z.object({
|
|
|
756
697
|
var verifyEmailSchema = import_zod.z.object({
|
|
757
698
|
code: import_zod.z.string().min(1, { message: "Verification code is required" })
|
|
758
699
|
});
|
|
759
|
-
var resendVerificationSchema = import_zod.z.object({
|
|
760
|
-
email: import_zod.z.string().email().optional()
|
|
761
|
-
});
|
|
762
700
|
var biometricVerifySchema = import_zod.z.object({});
|
|
763
701
|
var registerPushTokenSchema = import_zod.z.object({
|
|
764
702
|
pushToken: import_zod.z.string().min(1, { message: "Push token is required" })
|
|
@@ -772,19 +710,9 @@ var getTwofaSecretSchema = import_zod.z.object({
|
|
|
772
710
|
var disableTwofaSchema = import_zod.z.object({
|
|
773
711
|
password: import_zod.z.string().min(1, { message: "Password is required" })
|
|
774
712
|
});
|
|
775
|
-
var logoutSchema = import_zod.z.object({
|
|
776
|
-
allDevices: import_zod.z.boolean().optional().default(false)
|
|
777
|
-
});
|
|
778
713
|
var endAllSessionsSchema = import_zod.z.object({
|
|
779
714
|
skipCurrentSession: import_zod.z.boolean().optional().default(true)
|
|
780
715
|
});
|
|
781
|
-
var otpLoginRequestSchema = import_zod.z.object({
|
|
782
|
-
email: import_zod.z.string().email({ message: "Invalid email address" })
|
|
783
|
-
});
|
|
784
|
-
var otpLoginVerifySchema = import_zod.z.object({
|
|
785
|
-
email: import_zod.z.string().email(),
|
|
786
|
-
code: import_zod.z.number().min(1e5).max(999999)
|
|
787
|
-
});
|
|
788
716
|
function createSchemas(extensions) {
|
|
789
717
|
return {
|
|
790
718
|
signup: extensions?.signup ? signupSchema.merge(extensions.signup) : signupSchema,
|
|
@@ -863,31 +791,29 @@ var BaseProcedureFactory = class {
|
|
|
863
791
|
if (this.config.hooks?.onUserCreated) {
|
|
864
792
|
await this.config.hooks.onUserCreated(user.id, typedInput);
|
|
865
793
|
}
|
|
866
|
-
const refreshToken = (0, import_node_crypto.randomUUID)();
|
|
867
794
|
const extraSessionData = this.config.hooks?.getSessionData ? await this.config.hooks.getSessionData(typedInput) : {};
|
|
868
795
|
const session = await this.config.prisma.session.create({
|
|
869
796
|
data: {
|
|
870
797
|
userId: user.id,
|
|
871
798
|
browserName: detectBrowser(userAgent),
|
|
872
799
|
socketId: null,
|
|
873
|
-
refreshToken,
|
|
874
800
|
...extraSessionData
|
|
875
801
|
},
|
|
876
|
-
select: { id: true,
|
|
802
|
+
select: { id: true, userId: true }
|
|
877
803
|
});
|
|
878
804
|
if (this.config.hooks?.onSessionCreated) {
|
|
879
805
|
await this.config.hooks.onSessionCreated(session.id, typedInput);
|
|
880
806
|
}
|
|
881
|
-
const
|
|
807
|
+
const authToken = createAuthToken(
|
|
882
808
|
{ id: session.id, userId: session.userId, verifiedHumanAt: null },
|
|
883
809
|
{
|
|
884
810
|
secret: this.config.secrets.jwt,
|
|
885
|
-
expiresIn: this.config.tokenSettings.
|
|
811
|
+
expiresIn: this.config.tokenSettings.jwtExpiry
|
|
886
812
|
}
|
|
887
813
|
);
|
|
888
|
-
|
|
814
|
+
setAuthCookie(
|
|
889
815
|
ctx.res,
|
|
890
|
-
|
|
816
|
+
authToken,
|
|
891
817
|
this.config.cookieSettings,
|
|
892
818
|
this.config.storageKeys
|
|
893
819
|
);
|
|
@@ -979,19 +905,13 @@ var BaseProcedureFactory = class {
|
|
|
979
905
|
}
|
|
980
906
|
}
|
|
981
907
|
if (!validCode) {
|
|
982
|
-
const checkOTP = await this.config.prisma.
|
|
983
|
-
where: {
|
|
984
|
-
code: Number(code),
|
|
985
|
-
userId: user.id,
|
|
986
|
-
disabled: false,
|
|
987
|
-
createdAt: { gte: new Date(Date.now() - this.config.tokenSettings.otpValidityMs) }
|
|
988
|
-
}
|
|
908
|
+
const checkOTP = await this.config.prisma.oTP.findUnique({
|
|
909
|
+
where: { userId: user.id }
|
|
989
910
|
});
|
|
990
|
-
if (checkOTP) {
|
|
911
|
+
if (checkOTP && checkOTP.code === Number(code) && checkOTP.expiredAt >= /* @__PURE__ */ new Date()) {
|
|
991
912
|
validCode = true;
|
|
992
|
-
await this.config.prisma.
|
|
993
|
-
where: {
|
|
994
|
-
data: { disabled: true }
|
|
913
|
+
await this.config.prisma.oTP.delete({
|
|
914
|
+
where: { userId: user.id }
|
|
995
915
|
});
|
|
996
916
|
}
|
|
997
917
|
}
|
|
@@ -1002,19 +922,16 @@ var BaseProcedureFactory = class {
|
|
|
1002
922
|
});
|
|
1003
923
|
}
|
|
1004
924
|
}
|
|
1005
|
-
const refreshToken = (0, import_node_crypto.randomUUID)();
|
|
1006
925
|
const extraSessionData = this.config.hooks?.getSessionData ? await this.config.hooks.getSessionData(typedInput) : {};
|
|
1007
926
|
const session = await this.config.prisma.session.create({
|
|
1008
927
|
data: {
|
|
1009
928
|
userId: user.id,
|
|
1010
929
|
browserName: detectBrowser(userAgent),
|
|
1011
930
|
socketId: null,
|
|
1012
|
-
refreshToken,
|
|
1013
931
|
...extraSessionData
|
|
1014
932
|
},
|
|
1015
933
|
select: {
|
|
1016
934
|
id: true,
|
|
1017
|
-
refreshToken: true,
|
|
1018
935
|
userId: true,
|
|
1019
936
|
socketId: true,
|
|
1020
937
|
browserName: true,
|
|
@@ -1031,16 +948,16 @@ var BaseProcedureFactory = class {
|
|
|
1031
948
|
if (this.config.hooks?.onSessionCreated) {
|
|
1032
949
|
await this.config.hooks.onSessionCreated(session.id, typedInput);
|
|
1033
950
|
}
|
|
1034
|
-
const
|
|
951
|
+
const authToken = createAuthToken(
|
|
1035
952
|
{ id: session.id, userId: session.userId, verifiedHumanAt: user.verifiedHumanAt },
|
|
1036
953
|
{
|
|
1037
954
|
secret: this.config.secrets.jwt,
|
|
1038
|
-
expiresIn: this.config.tokenSettings.
|
|
955
|
+
expiresIn: this.config.tokenSettings.jwtExpiry
|
|
1039
956
|
}
|
|
1040
957
|
);
|
|
1041
|
-
|
|
958
|
+
setAuthCookie(
|
|
1042
959
|
ctx.res,
|
|
1043
|
-
|
|
960
|
+
authToken,
|
|
1044
961
|
this.config.cookieSettings,
|
|
1045
962
|
this.config.storageKeys
|
|
1046
963
|
);
|
|
@@ -1051,7 +968,7 @@ var BaseProcedureFactory = class {
|
|
|
1051
968
|
});
|
|
1052
969
|
}
|
|
1053
970
|
logout() {
|
|
1054
|
-
return this.
|
|
971
|
+
return this.authProcedure.meta({ ignoreExpiration: true }).mutation(async ({ ctx }) => {
|
|
1055
972
|
const { userId, sessionId } = ctx;
|
|
1056
973
|
if (sessionId) {
|
|
1057
974
|
await this.config.prisma.session.update({
|
|
@@ -1068,18 +985,17 @@ var BaseProcedureFactory = class {
|
|
|
1068
985
|
await this.config.hooks.afterLogout(userId, sessionId, ctx.socketId);
|
|
1069
986
|
}
|
|
1070
987
|
}
|
|
1071
|
-
|
|
988
|
+
clearAuthCookie(ctx.res, this.config.cookieSettings, this.config.storageKeys);
|
|
1072
989
|
return { success: true };
|
|
1073
990
|
});
|
|
1074
991
|
}
|
|
1075
992
|
refresh() {
|
|
1076
|
-
return this.authProcedure.
|
|
993
|
+
return this.authProcedure.query(async ({ ctx }) => {
|
|
1077
994
|
const session = await this.config.prisma.session.update({
|
|
1078
995
|
where: { id: ctx.sessionId },
|
|
1079
|
-
data: {
|
|
996
|
+
data: { lastUsed: /* @__PURE__ */ new Date() },
|
|
1080
997
|
select: {
|
|
1081
998
|
id: true,
|
|
1082
|
-
refreshToken: true,
|
|
1083
999
|
userId: true,
|
|
1084
1000
|
user: { select: { verifiedHumanAt: true } }
|
|
1085
1001
|
}
|
|
@@ -1088,16 +1004,16 @@ var BaseProcedureFactory = class {
|
|
|
1088
1004
|
this.config.hooks.onRefresh(session.userId).catch(() => {
|
|
1089
1005
|
});
|
|
1090
1006
|
}
|
|
1091
|
-
const
|
|
1007
|
+
const authToken = createAuthToken(
|
|
1092
1008
|
{ id: session.id, userId: session.userId, verifiedHumanAt: session.user.verifiedHumanAt },
|
|
1093
1009
|
{
|
|
1094
1010
|
secret: this.config.secrets.jwt,
|
|
1095
|
-
expiresIn: this.config.tokenSettings.
|
|
1011
|
+
expiresIn: this.config.tokenSettings.jwtExpiry
|
|
1096
1012
|
}
|
|
1097
1013
|
);
|
|
1098
|
-
|
|
1014
|
+
setAuthCookie(
|
|
1099
1015
|
ctx.res,
|
|
1100
|
-
|
|
1016
|
+
authToken,
|
|
1101
1017
|
this.config.cookieSettings,
|
|
1102
1018
|
this.config.storageKeys
|
|
1103
1019
|
);
|
|
@@ -1325,7 +1241,7 @@ var BiometricProcedureFactory = class {
|
|
|
1325
1241
|
};
|
|
1326
1242
|
|
|
1327
1243
|
// src/procedures/emailVerification.ts
|
|
1328
|
-
var
|
|
1244
|
+
var import_node_crypto = require("crypto");
|
|
1329
1245
|
var import_server4 = require("@trpc/server");
|
|
1330
1246
|
var EmailVerificationProcedureFactory = class {
|
|
1331
1247
|
constructor(config, authProcedure) {
|
|
@@ -1358,7 +1274,7 @@ var EmailVerificationProcedureFactory = class {
|
|
|
1358
1274
|
if (user.emailVerificationStatus === "VERIFIED") {
|
|
1359
1275
|
return { message: "Email is already verified", emailSent: false };
|
|
1360
1276
|
}
|
|
1361
|
-
const otp = (0,
|
|
1277
|
+
const otp = (0, import_node_crypto.randomUUID)();
|
|
1362
1278
|
await this.config.prisma.user.update({
|
|
1363
1279
|
where: { id: userId },
|
|
1364
1280
|
data: { emailVerificationStatus: "PENDING", otpForEmailVerification: otp }
|
|
@@ -1423,7 +1339,6 @@ var EmailVerificationProcedureFactory = class {
|
|
|
1423
1339
|
};
|
|
1424
1340
|
|
|
1425
1341
|
// src/procedures/oauth.ts
|
|
1426
|
-
var import_node_crypto3 = require("crypto");
|
|
1427
1342
|
var import_server5 = require("@trpc/server");
|
|
1428
1343
|
var OAuthLoginProcedureFactory = class {
|
|
1429
1344
|
constructor(config, procedure) {
|
|
@@ -1522,19 +1437,16 @@ var OAuthLoginProcedureFactory = class {
|
|
|
1522
1437
|
if (user.status === "BANNED") {
|
|
1523
1438
|
throw new import_server5.TRPCError({ code: "FORBIDDEN", message: "Your account has been banned." });
|
|
1524
1439
|
}
|
|
1525
|
-
const refreshToken = (0, import_node_crypto3.randomUUID)();
|
|
1526
1440
|
const extraSessionData = this.config.hooks?.getSessionData ? await this.config.hooks.getSessionData(typedInput) : {};
|
|
1527
1441
|
const session = await this.config.prisma.session.create({
|
|
1528
1442
|
data: {
|
|
1529
1443
|
userId: user.id,
|
|
1530
1444
|
browserName: detectBrowser(userAgent),
|
|
1531
1445
|
socketId: null,
|
|
1532
|
-
refreshToken,
|
|
1533
1446
|
...extraSessionData
|
|
1534
1447
|
},
|
|
1535
1448
|
select: {
|
|
1536
1449
|
id: true,
|
|
1537
|
-
refreshToken: true,
|
|
1538
1450
|
userId: true,
|
|
1539
1451
|
socketId: true,
|
|
1540
1452
|
browserName: true,
|
|
@@ -1551,16 +1463,16 @@ var OAuthLoginProcedureFactory = class {
|
|
|
1551
1463
|
if (this.config.hooks?.onSessionCreated) {
|
|
1552
1464
|
await this.config.hooks.onSessionCreated(session.id, typedInput);
|
|
1553
1465
|
}
|
|
1554
|
-
const
|
|
1466
|
+
const authToken = createAuthToken(
|
|
1555
1467
|
{ id: session.id, userId: session.userId, verifiedHumanAt: user.verifiedHumanAt ?? null },
|
|
1556
1468
|
{
|
|
1557
1469
|
secret: this.config.secrets.jwt,
|
|
1558
|
-
expiresIn: this.config.tokenSettings.
|
|
1470
|
+
expiresIn: this.config.tokenSettings.jwtExpiry
|
|
1559
1471
|
}
|
|
1560
1472
|
);
|
|
1561
|
-
|
|
1473
|
+
setAuthCookie(
|
|
1562
1474
|
ctx.res,
|
|
1563
|
-
|
|
1475
|
+
authToken,
|
|
1564
1476
|
this.config.cookieSettings,
|
|
1565
1477
|
this.config.storageKeys
|
|
1566
1478
|
);
|
|
@@ -1758,8 +1670,11 @@ var TwoFaProcedureFactory = class {
|
|
|
1758
1670
|
throw new import_server6.TRPCError({ code: "FORBIDDEN", message: "Invalid credentials." });
|
|
1759
1671
|
}
|
|
1760
1672
|
const otp = generateOtp();
|
|
1761
|
-
|
|
1762
|
-
|
|
1673
|
+
const expiredAt = new Date(Date.now() + this.config.tokenSettings.otpValidityMs);
|
|
1674
|
+
await this.config.prisma.oTP.upsert({
|
|
1675
|
+
where: { userId: user.id },
|
|
1676
|
+
update: { code: otp, expiredAt },
|
|
1677
|
+
create: { userId: user.id, code: otp, expiredAt }
|
|
1763
1678
|
});
|
|
1764
1679
|
if (this.config.emailService) {
|
|
1765
1680
|
await this.config.emailService.sendOTPEmail(user.email, otp);
|
|
@@ -1778,20 +1693,14 @@ var TwoFaProcedureFactory = class {
|
|
|
1778
1693
|
if (!user) {
|
|
1779
1694
|
throw new import_server6.TRPCError({ code: "NOT_FOUND", message: "User not found" });
|
|
1780
1695
|
}
|
|
1781
|
-
const otp = await this.config.prisma.
|
|
1782
|
-
where: {
|
|
1783
|
-
userId: user.id,
|
|
1784
|
-
code,
|
|
1785
|
-
disabled: false,
|
|
1786
|
-
createdAt: { gte: new Date(Date.now() - this.config.tokenSettings.otpValidityMs) }
|
|
1787
|
-
}
|
|
1696
|
+
const otp = await this.config.prisma.oTP.findUnique({
|
|
1697
|
+
where: { userId: user.id }
|
|
1788
1698
|
});
|
|
1789
|
-
if (!otp) {
|
|
1699
|
+
if (!otp || otp.code !== code || otp.expiredAt < /* @__PURE__ */ new Date()) {
|
|
1790
1700
|
throw new import_server6.TRPCError({ code: "FORBIDDEN", message: "Invalid or expired OTP" });
|
|
1791
1701
|
}
|
|
1792
|
-
await this.config.prisma.
|
|
1793
|
-
where: {
|
|
1794
|
-
data: { disabled: true }
|
|
1702
|
+
await this.config.prisma.oTP.delete({
|
|
1703
|
+
where: { userId: user.id }
|
|
1795
1704
|
});
|
|
1796
1705
|
await this.config.prisma.user.update({
|
|
1797
1706
|
where: { id: user.id },
|
|
@@ -1844,7 +1753,7 @@ var TwoFaProcedureFactory = class {
|
|
|
1844
1753
|
});
|
|
1845
1754
|
}
|
|
1846
1755
|
deregisterPushToken() {
|
|
1847
|
-
return this.authProcedure.
|
|
1756
|
+
return this.authProcedure.input(deregisterPushTokenSchema).mutation(async ({ ctx, input }) => {
|
|
1848
1757
|
this.checkConfig();
|
|
1849
1758
|
const { userId } = ctx;
|
|
1850
1759
|
const { pushToken } = input;
|
|
@@ -1963,7 +1872,6 @@ var createContext = ({ req, res }) => ({
|
|
|
1963
1872
|
headers: req.headers,
|
|
1964
1873
|
userId: null,
|
|
1965
1874
|
sessionId: null,
|
|
1966
|
-
refreshToken: null,
|
|
1967
1875
|
socketId: null,
|
|
1968
1876
|
ip: getClientIp(req),
|
|
1969
1877
|
res
|
|
@@ -2023,12 +1931,12 @@ function createAuthRouter(config) {
|
|
|
2023
1931
|
biometricVerifySchema,
|
|
2024
1932
|
changePasswordSchema,
|
|
2025
1933
|
cleanBase32String,
|
|
2026
|
-
|
|
1934
|
+
clearAuthCookie,
|
|
2027
1935
|
comparePassword,
|
|
2028
|
-
createAccessToken,
|
|
2029
1936
|
createAuthConfig,
|
|
2030
1937
|
createAuthGuard,
|
|
2031
1938
|
createAuthRouter,
|
|
1939
|
+
createAuthToken,
|
|
2032
1940
|
createConsoleEmailAdapter,
|
|
2033
1941
|
createNoopEmailAdapter,
|
|
2034
1942
|
createOAuthVerifier,
|
|
@@ -2048,20 +1956,16 @@ function createAuthRouter(config) {
|
|
|
2048
1956
|
isTokenExpiredError,
|
|
2049
1957
|
isTokenInvalidError,
|
|
2050
1958
|
loginSchema,
|
|
2051
|
-
logoutSchema,
|
|
2052
1959
|
oAuthLoginSchema,
|
|
2053
|
-
|
|
2054
|
-
otpLoginVerifySchema,
|
|
2055
|
-
parseAuthCookies,
|
|
1960
|
+
parseAuthCookie,
|
|
2056
1961
|
requestPasswordResetSchema,
|
|
2057
1962
|
resetPasswordSchema,
|
|
2058
|
-
|
|
1963
|
+
setAuthCookie,
|
|
2059
1964
|
signupSchema,
|
|
2060
1965
|
twoFaResetSchema,
|
|
2061
|
-
twoFaSetupSchema,
|
|
2062
1966
|
twoFaVerifySchema,
|
|
2063
1967
|
validatePasswordStrength,
|
|
2064
|
-
|
|
1968
|
+
verifyAuthToken,
|
|
2065
1969
|
verifyEmailSchema,
|
|
2066
1970
|
verifyTotp
|
|
2067
1971
|
});
|