@factiii/auth 0.2.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 +115 -191
- package/dist/index.mjs +111 -171
- 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.mjs
CHANGED
|
@@ -8,20 +8,16 @@ import {
|
|
|
8
8
|
endAllSessionsSchema,
|
|
9
9
|
getTwofaSecretSchema,
|
|
10
10
|
loginSchema,
|
|
11
|
-
logoutSchema,
|
|
12
11
|
oAuthLoginSchema,
|
|
13
|
-
otpLoginRequestSchema,
|
|
14
|
-
otpLoginVerifySchema,
|
|
15
12
|
registerPushTokenSchema,
|
|
16
13
|
requestPasswordResetSchema,
|
|
17
14
|
resetPasswordSchema,
|
|
18
15
|
signupSchema,
|
|
19
16
|
twoFaResetSchema,
|
|
20
17
|
twoFaResetVerifySchema,
|
|
21
|
-
twoFaSetupSchema,
|
|
22
18
|
twoFaVerifySchema,
|
|
23
19
|
verifyEmailSchema
|
|
24
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-EHI4P63M.mjs";
|
|
25
21
|
|
|
26
22
|
// src/middleware/authGuard.ts
|
|
27
23
|
import { TRPCError } from "@trpc/server";
|
|
@@ -81,7 +77,8 @@ function createConsoleEmailAdapter() {
|
|
|
81
77
|
|
|
82
78
|
// src/utilities/config.ts
|
|
83
79
|
var defaultTokenSettings = {
|
|
84
|
-
|
|
80
|
+
jwtExpiry: 30 * 24 * 60 * 60,
|
|
81
|
+
// 30 days in seconds
|
|
85
82
|
passwordResetExpiryMs: 60 * 60 * 1e3,
|
|
86
83
|
// 1 hour
|
|
87
84
|
otpValidityMs: 15 * 60 * 1e3
|
|
@@ -90,15 +87,13 @@ var defaultTokenSettings = {
|
|
|
90
87
|
var defaultCookieSettings = {
|
|
91
88
|
secure: true,
|
|
92
89
|
sameSite: "Strict",
|
|
93
|
-
httpOnly:
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
// 1 year in seconds
|
|
90
|
+
httpOnly: false,
|
|
91
|
+
path: "/",
|
|
92
|
+
maxAge: 30 * 24 * 60 * 60
|
|
93
|
+
// 30 days in seconds
|
|
98
94
|
};
|
|
99
95
|
var defaultStorageKeys = {
|
|
100
|
-
|
|
101
|
-
refreshToken: "auth-rt"
|
|
96
|
+
authToken: "auth-token"
|
|
102
97
|
};
|
|
103
98
|
var defaultFeatures = {
|
|
104
99
|
twoFa: true,
|
|
@@ -130,21 +125,17 @@ var defaultAuthConfig = {
|
|
|
130
125
|
|
|
131
126
|
// src/utilities/cookies.ts
|
|
132
127
|
var DEFAULT_STORAGE_KEYS = {
|
|
133
|
-
|
|
134
|
-
REFRESH_TOKEN: "auth-rt"
|
|
128
|
+
AUTH_TOKEN: "auth-token"
|
|
135
129
|
};
|
|
136
|
-
function
|
|
137
|
-
|
|
138
|
-
refreshToken: DEFAULT_STORAGE_KEYS.REFRESH_TOKEN
|
|
130
|
+
function parseAuthCookie(cookieHeader, storageKeys = {
|
|
131
|
+
authToken: DEFAULT_STORAGE_KEYS.AUTH_TOKEN
|
|
139
132
|
}) {
|
|
140
133
|
if (!cookieHeader) {
|
|
141
134
|
return {};
|
|
142
135
|
}
|
|
143
|
-
const
|
|
144
|
-
const refreshToken = cookieHeader.split(`${storageKeys.refreshToken}=`)[1]?.split(";")[0];
|
|
136
|
+
const authToken = cookieHeader.split(`${storageKeys.authToken}=`)[1]?.split(";")[0];
|
|
145
137
|
return {
|
|
146
|
-
|
|
147
|
-
refreshToken: refreshToken || void 0
|
|
138
|
+
authToken: authToken || void 0
|
|
148
139
|
};
|
|
149
140
|
}
|
|
150
141
|
function extractDomain(req) {
|
|
@@ -168,76 +159,47 @@ function extractDomain(req) {
|
|
|
168
159
|
}
|
|
169
160
|
return void 0;
|
|
170
161
|
}
|
|
171
|
-
function
|
|
172
|
-
|
|
173
|
-
refreshToken: DEFAULT_STORAGE_KEYS.REFRESH_TOKEN
|
|
162
|
+
function setAuthCookie(res, authToken, settings, storageKeys = {
|
|
163
|
+
authToken: DEFAULT_STORAGE_KEYS.AUTH_TOKEN
|
|
174
164
|
}) {
|
|
175
|
-
const cookies = [];
|
|
176
165
|
const domain = settings.domain ?? extractDomain(res.req);
|
|
177
166
|
const expiresDate = settings.maxAge ? new Date(Date.now() + settings.maxAge * 1e3).toUTCString() : void 0;
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
cookies.push(refreshCookie);
|
|
189
|
-
}
|
|
190
|
-
if (credentials.accessToken) {
|
|
191
|
-
const accessCookie = [
|
|
192
|
-
`${storageKeys.accessToken}=${credentials.accessToken}`,
|
|
193
|
-
settings.secure ? "Secure=true" : "",
|
|
194
|
-
`SameSite=${settings.sameSite}`,
|
|
195
|
-
`Path=${settings.accessTokenPath}`,
|
|
196
|
-
domain ? `Domain=${domain}` : "",
|
|
197
|
-
`Expires=${expiresDate}`
|
|
198
|
-
].filter(Boolean).join("; ");
|
|
199
|
-
cookies.push(accessCookie);
|
|
200
|
-
}
|
|
201
|
-
if (cookies.length > 0) {
|
|
202
|
-
res.setHeader("Set-Cookie", cookies);
|
|
203
|
-
}
|
|
167
|
+
const cookie = [
|
|
168
|
+
`${storageKeys.authToken}=${authToken}`,
|
|
169
|
+
settings.httpOnly ? "HttpOnly" : "",
|
|
170
|
+
settings.secure ? "Secure=true" : "",
|
|
171
|
+
`SameSite=${settings.sameSite}`,
|
|
172
|
+
`Path=${settings.path ?? "/"}`,
|
|
173
|
+
domain ? `Domain=${domain}` : "",
|
|
174
|
+
expiresDate ? `Expires=${expiresDate}` : ""
|
|
175
|
+
].filter(Boolean).join("; ");
|
|
176
|
+
res.setHeader("Set-Cookie", cookie);
|
|
204
177
|
}
|
|
205
|
-
function
|
|
206
|
-
|
|
207
|
-
refreshToken: DEFAULT_STORAGE_KEYS.REFRESH_TOKEN
|
|
178
|
+
function clearAuthCookie(res, settings, storageKeys = {
|
|
179
|
+
authToken: DEFAULT_STORAGE_KEYS.AUTH_TOKEN
|
|
208
180
|
}) {
|
|
209
181
|
const domain = extractDomain(res.req);
|
|
210
182
|
const expiredDate = (/* @__PURE__ */ new Date(0)).toUTCString();
|
|
211
|
-
const
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
[
|
|
222
|
-
`${storageKeys.accessToken}=destroy`,
|
|
223
|
-
settings.secure ? "Secure=true" : "",
|
|
224
|
-
`SameSite=${settings.sameSite}`,
|
|
225
|
-
`Path=${settings.accessTokenPath}`,
|
|
226
|
-
domain ? `Domain=${domain}` : "",
|
|
227
|
-
`Expires=${expiredDate}`
|
|
228
|
-
].filter(Boolean).join("; ")
|
|
229
|
-
];
|
|
230
|
-
res.setHeader("Set-Cookie", cookies);
|
|
183
|
+
const cookie = [
|
|
184
|
+
`${storageKeys.authToken}=destroy`,
|
|
185
|
+
settings.httpOnly ? "HttpOnly" : "",
|
|
186
|
+
settings.secure ? "Secure=true" : "",
|
|
187
|
+
`SameSite=${settings.sameSite}`,
|
|
188
|
+
`Path=${settings.path ?? "/"}`,
|
|
189
|
+
domain ? `Domain=${domain}` : "",
|
|
190
|
+
`Expires=${expiredDate}`
|
|
191
|
+
].filter(Boolean).join("; ");
|
|
192
|
+
res.setHeader("Set-Cookie", cookie);
|
|
231
193
|
}
|
|
232
194
|
|
|
233
195
|
// src/utilities/jwt.ts
|
|
234
196
|
import jwt from "jsonwebtoken";
|
|
235
|
-
function
|
|
197
|
+
function createAuthToken(payload, options) {
|
|
236
198
|
return jwt.sign(payload, options.secret, {
|
|
237
199
|
expiresIn: options.expiresIn
|
|
238
200
|
});
|
|
239
201
|
}
|
|
240
|
-
function
|
|
202
|
+
function verifyAuthToken(token, options) {
|
|
241
203
|
return jwt.verify(token, options.secret, {
|
|
242
204
|
ignoreExpiration: options.ignoreExpiration ?? false
|
|
243
205
|
});
|
|
@@ -264,9 +226,10 @@ function createAuthGuard(config, t) {
|
|
|
264
226
|
const storageKeys = config.storageKeys ?? defaultStorageKeys;
|
|
265
227
|
const cookieSettings = { ...defaultCookieSettings, ...config.cookieSettings };
|
|
266
228
|
const revokeSession = async (ctx, sessionId, description, errorStack, path) => {
|
|
267
|
-
|
|
229
|
+
clearAuthCookie(ctx.res, cookieSettings, storageKeys);
|
|
268
230
|
if (config.hooks?.logError) {
|
|
269
231
|
try {
|
|
232
|
+
const cookieHeader = ctx.headers.cookie;
|
|
270
233
|
const contextInfo = {
|
|
271
234
|
reason: description,
|
|
272
235
|
sessionId,
|
|
@@ -274,6 +237,10 @@ function createAuthGuard(config, t) {
|
|
|
274
237
|
ip: ctx.ip,
|
|
275
238
|
userAgent: ctx.headers["user-agent"],
|
|
276
239
|
...path ? { path } : {},
|
|
240
|
+
hasCookieHeader: Boolean(cookieHeader),
|
|
241
|
+
cookieKeys: cookieHeader ? cookieHeader.split(";").map((c) => c.trim().split("=")[0]).filter(Boolean) : [],
|
|
242
|
+
origin: ctx.headers.origin ?? null,
|
|
243
|
+
referer: ctx.headers.referer ?? null,
|
|
277
244
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
278
245
|
};
|
|
279
246
|
const combinedStack = [
|
|
@@ -312,9 +279,8 @@ ${errorStack}` : null,
|
|
|
312
279
|
}
|
|
313
280
|
};
|
|
314
281
|
const authGuard = t.middleware(async ({ ctx, meta, next, path }) => {
|
|
315
|
-
const cookies =
|
|
316
|
-
const authToken = cookies.
|
|
317
|
-
const refreshToken = cookies.refreshToken;
|
|
282
|
+
const cookies = parseAuthCookie(ctx.headers.cookie, storageKeys);
|
|
283
|
+
const authToken = cookies.authToken;
|
|
318
284
|
const userAgent = ctx.headers["user-agent"];
|
|
319
285
|
if (!userAgent) {
|
|
320
286
|
throw new TRPCError({
|
|
@@ -324,27 +290,13 @@ ${errorStack}` : null,
|
|
|
324
290
|
}
|
|
325
291
|
if (authToken) {
|
|
326
292
|
try {
|
|
327
|
-
const decodedToken =
|
|
293
|
+
const decodedToken = verifyAuthToken(authToken, {
|
|
328
294
|
secret: config.secrets.jwt,
|
|
329
295
|
ignoreExpiration: meta?.ignoreExpiration ?? false
|
|
330
296
|
});
|
|
331
|
-
if (path === "auth.refresh" && !refreshToken) {
|
|
332
|
-
await revokeSession(
|
|
333
|
-
ctx,
|
|
334
|
-
decodedToken.id,
|
|
335
|
-
"Session revoked: No refresh token",
|
|
336
|
-
void 0,
|
|
337
|
-
path
|
|
338
|
-
);
|
|
339
|
-
throw new TRPCError({
|
|
340
|
-
message: "Unauthorized",
|
|
341
|
-
code: "UNAUTHORIZED"
|
|
342
|
-
});
|
|
343
|
-
}
|
|
344
297
|
const session = await config.prisma.session.findUnique({
|
|
345
298
|
where: {
|
|
346
|
-
id: decodedToken.id
|
|
347
|
-
...path === "auth.refresh" ? { refreshToken } : {}
|
|
299
|
+
id: decodedToken.id
|
|
348
300
|
},
|
|
349
301
|
select: {
|
|
350
302
|
userId: true,
|
|
@@ -435,8 +387,7 @@ ${errorStack}` : null,
|
|
|
435
387
|
...ctx,
|
|
436
388
|
userId: session.userId,
|
|
437
389
|
socketId: session.socketId,
|
|
438
|
-
sessionId: session.id
|
|
439
|
-
refreshToken
|
|
390
|
+
sessionId: session.id
|
|
440
391
|
}
|
|
441
392
|
});
|
|
442
393
|
} catch (err) {
|
|
@@ -481,7 +432,6 @@ ${errorStack}` : null,
|
|
|
481
432
|
}
|
|
482
433
|
|
|
483
434
|
// src/procedures/base.ts
|
|
484
|
-
import { randomUUID } from "crypto";
|
|
485
435
|
import { TRPCError as TRPCError2 } from "@trpc/server";
|
|
486
436
|
|
|
487
437
|
// src/utilities/browser.ts
|
|
@@ -707,31 +657,29 @@ var BaseProcedureFactory = class {
|
|
|
707
657
|
if (this.config.hooks?.onUserCreated) {
|
|
708
658
|
await this.config.hooks.onUserCreated(user.id, typedInput);
|
|
709
659
|
}
|
|
710
|
-
const refreshToken = randomUUID();
|
|
711
660
|
const extraSessionData = this.config.hooks?.getSessionData ? await this.config.hooks.getSessionData(typedInput) : {};
|
|
712
661
|
const session = await this.config.prisma.session.create({
|
|
713
662
|
data: {
|
|
714
663
|
userId: user.id,
|
|
715
664
|
browserName: detectBrowser(userAgent),
|
|
716
665
|
socketId: null,
|
|
717
|
-
refreshToken,
|
|
718
666
|
...extraSessionData
|
|
719
667
|
},
|
|
720
|
-
select: { id: true,
|
|
668
|
+
select: { id: true, userId: true }
|
|
721
669
|
});
|
|
722
670
|
if (this.config.hooks?.onSessionCreated) {
|
|
723
671
|
await this.config.hooks.onSessionCreated(session.id, typedInput);
|
|
724
672
|
}
|
|
725
|
-
const
|
|
673
|
+
const authToken = createAuthToken(
|
|
726
674
|
{ id: session.id, userId: session.userId, verifiedHumanAt: null },
|
|
727
675
|
{
|
|
728
676
|
secret: this.config.secrets.jwt,
|
|
729
|
-
expiresIn: this.config.tokenSettings.
|
|
677
|
+
expiresIn: this.config.tokenSettings.jwtExpiry
|
|
730
678
|
}
|
|
731
679
|
);
|
|
732
|
-
|
|
680
|
+
setAuthCookie(
|
|
733
681
|
ctx.res,
|
|
734
|
-
|
|
682
|
+
authToken,
|
|
735
683
|
this.config.cookieSettings,
|
|
736
684
|
this.config.storageKeys
|
|
737
685
|
);
|
|
@@ -823,19 +771,13 @@ var BaseProcedureFactory = class {
|
|
|
823
771
|
}
|
|
824
772
|
}
|
|
825
773
|
if (!validCode) {
|
|
826
|
-
const checkOTP = await this.config.prisma.
|
|
827
|
-
where: {
|
|
828
|
-
code: Number(code),
|
|
829
|
-
userId: user.id,
|
|
830
|
-
disabled: false,
|
|
831
|
-
createdAt: { gte: new Date(Date.now() - this.config.tokenSettings.otpValidityMs) }
|
|
832
|
-
}
|
|
774
|
+
const checkOTP = await this.config.prisma.oTP.findUnique({
|
|
775
|
+
where: { userId: user.id }
|
|
833
776
|
});
|
|
834
|
-
if (checkOTP) {
|
|
777
|
+
if (checkOTP && checkOTP.code === Number(code) && checkOTP.expiredAt >= /* @__PURE__ */ new Date()) {
|
|
835
778
|
validCode = true;
|
|
836
|
-
await this.config.prisma.
|
|
837
|
-
where: {
|
|
838
|
-
data: { disabled: true }
|
|
779
|
+
await this.config.prisma.oTP.delete({
|
|
780
|
+
where: { userId: user.id }
|
|
839
781
|
});
|
|
840
782
|
}
|
|
841
783
|
}
|
|
@@ -846,19 +788,16 @@ var BaseProcedureFactory = class {
|
|
|
846
788
|
});
|
|
847
789
|
}
|
|
848
790
|
}
|
|
849
|
-
const refreshToken = randomUUID();
|
|
850
791
|
const extraSessionData = this.config.hooks?.getSessionData ? await this.config.hooks.getSessionData(typedInput) : {};
|
|
851
792
|
const session = await this.config.prisma.session.create({
|
|
852
793
|
data: {
|
|
853
794
|
userId: user.id,
|
|
854
795
|
browserName: detectBrowser(userAgent),
|
|
855
796
|
socketId: null,
|
|
856
|
-
refreshToken,
|
|
857
797
|
...extraSessionData
|
|
858
798
|
},
|
|
859
799
|
select: {
|
|
860
800
|
id: true,
|
|
861
|
-
refreshToken: true,
|
|
862
801
|
userId: true,
|
|
863
802
|
socketId: true,
|
|
864
803
|
browserName: true,
|
|
@@ -875,16 +814,16 @@ var BaseProcedureFactory = class {
|
|
|
875
814
|
if (this.config.hooks?.onSessionCreated) {
|
|
876
815
|
await this.config.hooks.onSessionCreated(session.id, typedInput);
|
|
877
816
|
}
|
|
878
|
-
const
|
|
817
|
+
const authToken = createAuthToken(
|
|
879
818
|
{ id: session.id, userId: session.userId, verifiedHumanAt: user.verifiedHumanAt },
|
|
880
819
|
{
|
|
881
820
|
secret: this.config.secrets.jwt,
|
|
882
|
-
expiresIn: this.config.tokenSettings.
|
|
821
|
+
expiresIn: this.config.tokenSettings.jwtExpiry
|
|
883
822
|
}
|
|
884
823
|
);
|
|
885
|
-
|
|
824
|
+
setAuthCookie(
|
|
886
825
|
ctx.res,
|
|
887
|
-
|
|
826
|
+
authToken,
|
|
888
827
|
this.config.cookieSettings,
|
|
889
828
|
this.config.storageKeys
|
|
890
829
|
);
|
|
@@ -895,7 +834,7 @@ var BaseProcedureFactory = class {
|
|
|
895
834
|
});
|
|
896
835
|
}
|
|
897
836
|
logout() {
|
|
898
|
-
return this.
|
|
837
|
+
return this.authProcedure.meta({ ignoreExpiration: true }).mutation(async ({ ctx }) => {
|
|
899
838
|
const { userId, sessionId } = ctx;
|
|
900
839
|
if (sessionId) {
|
|
901
840
|
await this.config.prisma.session.update({
|
|
@@ -912,18 +851,17 @@ var BaseProcedureFactory = class {
|
|
|
912
851
|
await this.config.hooks.afterLogout(userId, sessionId, ctx.socketId);
|
|
913
852
|
}
|
|
914
853
|
}
|
|
915
|
-
|
|
854
|
+
clearAuthCookie(ctx.res, this.config.cookieSettings, this.config.storageKeys);
|
|
916
855
|
return { success: true };
|
|
917
856
|
});
|
|
918
857
|
}
|
|
919
858
|
refresh() {
|
|
920
|
-
return this.authProcedure.
|
|
859
|
+
return this.authProcedure.query(async ({ ctx }) => {
|
|
921
860
|
const session = await this.config.prisma.session.update({
|
|
922
861
|
where: { id: ctx.sessionId },
|
|
923
|
-
data: {
|
|
862
|
+
data: { lastUsed: /* @__PURE__ */ new Date() },
|
|
924
863
|
select: {
|
|
925
864
|
id: true,
|
|
926
|
-
refreshToken: true,
|
|
927
865
|
userId: true,
|
|
928
866
|
user: { select: { verifiedHumanAt: true } }
|
|
929
867
|
}
|
|
@@ -932,16 +870,16 @@ var BaseProcedureFactory = class {
|
|
|
932
870
|
this.config.hooks.onRefresh(session.userId).catch(() => {
|
|
933
871
|
});
|
|
934
872
|
}
|
|
935
|
-
const
|
|
873
|
+
const authToken = createAuthToken(
|
|
936
874
|
{ id: session.id, userId: session.userId, verifiedHumanAt: session.user.verifiedHumanAt },
|
|
937
875
|
{
|
|
938
876
|
secret: this.config.secrets.jwt,
|
|
939
|
-
expiresIn: this.config.tokenSettings.
|
|
877
|
+
expiresIn: this.config.tokenSettings.jwtExpiry
|
|
940
878
|
}
|
|
941
879
|
);
|
|
942
|
-
|
|
880
|
+
setAuthCookie(
|
|
943
881
|
ctx.res,
|
|
944
|
-
|
|
882
|
+
authToken,
|
|
945
883
|
this.config.cookieSettings,
|
|
946
884
|
this.config.storageKeys
|
|
947
885
|
);
|
|
@@ -1169,7 +1107,7 @@ var BiometricProcedureFactory = class {
|
|
|
1169
1107
|
};
|
|
1170
1108
|
|
|
1171
1109
|
// src/procedures/emailVerification.ts
|
|
1172
|
-
import { randomUUID
|
|
1110
|
+
import { randomUUID } from "crypto";
|
|
1173
1111
|
import { TRPCError as TRPCError4 } from "@trpc/server";
|
|
1174
1112
|
var EmailVerificationProcedureFactory = class {
|
|
1175
1113
|
constructor(config, authProcedure) {
|
|
@@ -1202,7 +1140,7 @@ var EmailVerificationProcedureFactory = class {
|
|
|
1202
1140
|
if (user.emailVerificationStatus === "VERIFIED") {
|
|
1203
1141
|
return { message: "Email is already verified", emailSent: false };
|
|
1204
1142
|
}
|
|
1205
|
-
const otp =
|
|
1143
|
+
const otp = randomUUID();
|
|
1206
1144
|
await this.config.prisma.user.update({
|
|
1207
1145
|
where: { id: userId },
|
|
1208
1146
|
data: { emailVerificationStatus: "PENDING", otpForEmailVerification: otp }
|
|
@@ -1267,7 +1205,6 @@ var EmailVerificationProcedureFactory = class {
|
|
|
1267
1205
|
};
|
|
1268
1206
|
|
|
1269
1207
|
// src/procedures/oauth.ts
|
|
1270
|
-
import { randomUUID as randomUUID3 } from "crypto";
|
|
1271
1208
|
import { TRPCError as TRPCError5 } from "@trpc/server";
|
|
1272
1209
|
var OAuthLoginProcedureFactory = class {
|
|
1273
1210
|
constructor(config, procedure) {
|
|
@@ -1366,19 +1303,16 @@ var OAuthLoginProcedureFactory = class {
|
|
|
1366
1303
|
if (user.status === "BANNED") {
|
|
1367
1304
|
throw new TRPCError5({ code: "FORBIDDEN", message: "Your account has been banned." });
|
|
1368
1305
|
}
|
|
1369
|
-
const refreshToken = randomUUID3();
|
|
1370
1306
|
const extraSessionData = this.config.hooks?.getSessionData ? await this.config.hooks.getSessionData(typedInput) : {};
|
|
1371
1307
|
const session = await this.config.prisma.session.create({
|
|
1372
1308
|
data: {
|
|
1373
1309
|
userId: user.id,
|
|
1374
1310
|
browserName: detectBrowser(userAgent),
|
|
1375
1311
|
socketId: null,
|
|
1376
|
-
refreshToken,
|
|
1377
1312
|
...extraSessionData
|
|
1378
1313
|
},
|
|
1379
1314
|
select: {
|
|
1380
1315
|
id: true,
|
|
1381
|
-
refreshToken: true,
|
|
1382
1316
|
userId: true,
|
|
1383
1317
|
socketId: true,
|
|
1384
1318
|
browserName: true,
|
|
@@ -1395,16 +1329,16 @@ var OAuthLoginProcedureFactory = class {
|
|
|
1395
1329
|
if (this.config.hooks?.onSessionCreated) {
|
|
1396
1330
|
await this.config.hooks.onSessionCreated(session.id, typedInput);
|
|
1397
1331
|
}
|
|
1398
|
-
const
|
|
1332
|
+
const authToken = createAuthToken(
|
|
1399
1333
|
{ id: session.id, userId: session.userId, verifiedHumanAt: user.verifiedHumanAt ?? null },
|
|
1400
1334
|
{
|
|
1401
1335
|
secret: this.config.secrets.jwt,
|
|
1402
|
-
expiresIn: this.config.tokenSettings.
|
|
1336
|
+
expiresIn: this.config.tokenSettings.jwtExpiry
|
|
1403
1337
|
}
|
|
1404
1338
|
);
|
|
1405
|
-
|
|
1339
|
+
setAuthCookie(
|
|
1406
1340
|
ctx.res,
|
|
1407
|
-
|
|
1341
|
+
authToken,
|
|
1408
1342
|
this.config.cookieSettings,
|
|
1409
1343
|
this.config.storageKeys
|
|
1410
1344
|
);
|
|
@@ -1602,8 +1536,11 @@ var TwoFaProcedureFactory = class {
|
|
|
1602
1536
|
throw new TRPCError6({ code: "FORBIDDEN", message: "Invalid credentials." });
|
|
1603
1537
|
}
|
|
1604
1538
|
const otp = generateOtp();
|
|
1605
|
-
|
|
1606
|
-
|
|
1539
|
+
const expiredAt = new Date(Date.now() + this.config.tokenSettings.otpValidityMs);
|
|
1540
|
+
await this.config.prisma.oTP.upsert({
|
|
1541
|
+
where: { userId: user.id },
|
|
1542
|
+
update: { code: otp, expiredAt },
|
|
1543
|
+
create: { userId: user.id, code: otp, expiredAt }
|
|
1607
1544
|
});
|
|
1608
1545
|
if (this.config.emailService) {
|
|
1609
1546
|
await this.config.emailService.sendOTPEmail(user.email, otp);
|
|
@@ -1622,20 +1559,14 @@ var TwoFaProcedureFactory = class {
|
|
|
1622
1559
|
if (!user) {
|
|
1623
1560
|
throw new TRPCError6({ code: "NOT_FOUND", message: "User not found" });
|
|
1624
1561
|
}
|
|
1625
|
-
const otp = await this.config.prisma.
|
|
1626
|
-
where: {
|
|
1627
|
-
userId: user.id,
|
|
1628
|
-
code,
|
|
1629
|
-
disabled: false,
|
|
1630
|
-
createdAt: { gte: new Date(Date.now() - this.config.tokenSettings.otpValidityMs) }
|
|
1631
|
-
}
|
|
1562
|
+
const otp = await this.config.prisma.oTP.findUnique({
|
|
1563
|
+
where: { userId: user.id }
|
|
1632
1564
|
});
|
|
1633
|
-
if (!otp) {
|
|
1565
|
+
if (!otp || otp.code !== code || otp.expiredAt < /* @__PURE__ */ new Date()) {
|
|
1634
1566
|
throw new TRPCError6({ code: "FORBIDDEN", message: "Invalid or expired OTP" });
|
|
1635
1567
|
}
|
|
1636
|
-
await this.config.prisma.
|
|
1637
|
-
where: {
|
|
1638
|
-
data: { disabled: true }
|
|
1568
|
+
await this.config.prisma.oTP.delete({
|
|
1569
|
+
where: { userId: user.id }
|
|
1639
1570
|
});
|
|
1640
1571
|
await this.config.prisma.user.update({
|
|
1641
1572
|
where: { id: user.id },
|
|
@@ -1688,21 +1619,35 @@ var TwoFaProcedureFactory = class {
|
|
|
1688
1619
|
});
|
|
1689
1620
|
}
|
|
1690
1621
|
deregisterPushToken() {
|
|
1691
|
-
return this.authProcedure.
|
|
1622
|
+
return this.authProcedure.input(deregisterPushTokenSchema).mutation(async ({ ctx, input }) => {
|
|
1692
1623
|
this.checkConfig();
|
|
1693
1624
|
const { userId } = ctx;
|
|
1694
1625
|
const { pushToken } = input;
|
|
1695
1626
|
const device = await this.config.prisma.device.findFirst({
|
|
1696
1627
|
where: {
|
|
1697
|
-
|
|
1628
|
+
users: { some: { id: userId } },
|
|
1698
1629
|
pushToken
|
|
1699
1630
|
},
|
|
1700
1631
|
select: { id: true }
|
|
1701
1632
|
});
|
|
1702
1633
|
if (device) {
|
|
1703
|
-
await this.config.prisma.
|
|
1704
|
-
where: {
|
|
1634
|
+
await this.config.prisma.session.updateMany({
|
|
1635
|
+
where: { userId, deviceId: device.id },
|
|
1636
|
+
data: { deviceId: null }
|
|
1637
|
+
});
|
|
1638
|
+
await this.config.prisma.device.update({
|
|
1639
|
+
where: { id: device.id },
|
|
1640
|
+
data: { users: { disconnect: { id: userId } } }
|
|
1705
1641
|
});
|
|
1642
|
+
const remainingUsers = await this.config.prisma.device.findUnique({
|
|
1643
|
+
where: { id: device.id },
|
|
1644
|
+
select: { users: { select: { id: true }, take: 1 } }
|
|
1645
|
+
});
|
|
1646
|
+
if (!remainingUsers?.users.length) {
|
|
1647
|
+
await this.config.prisma.device.delete({
|
|
1648
|
+
where: { id: device.id }
|
|
1649
|
+
});
|
|
1650
|
+
}
|
|
1706
1651
|
}
|
|
1707
1652
|
return { deregistered: true };
|
|
1708
1653
|
});
|
|
@@ -1793,7 +1738,6 @@ var createContext = ({ req, res }) => ({
|
|
|
1793
1738
|
headers: req.headers,
|
|
1794
1739
|
userId: null,
|
|
1795
1740
|
sessionId: null,
|
|
1796
|
-
refreshToken: null,
|
|
1797
1741
|
socketId: null,
|
|
1798
1742
|
ip: getClientIp(req),
|
|
1799
1743
|
res
|
|
@@ -1852,12 +1796,12 @@ export {
|
|
|
1852
1796
|
biometricVerifySchema,
|
|
1853
1797
|
changePasswordSchema,
|
|
1854
1798
|
cleanBase32String,
|
|
1855
|
-
|
|
1799
|
+
clearAuthCookie,
|
|
1856
1800
|
comparePassword,
|
|
1857
|
-
createAccessToken,
|
|
1858
1801
|
createAuthConfig,
|
|
1859
1802
|
createAuthGuard,
|
|
1860
1803
|
createAuthRouter,
|
|
1804
|
+
createAuthToken,
|
|
1861
1805
|
createConsoleEmailAdapter,
|
|
1862
1806
|
createNoopEmailAdapter,
|
|
1863
1807
|
createOAuthVerifier,
|
|
@@ -1877,20 +1821,16 @@ export {
|
|
|
1877
1821
|
isTokenExpiredError,
|
|
1878
1822
|
isTokenInvalidError,
|
|
1879
1823
|
loginSchema,
|
|
1880
|
-
logoutSchema,
|
|
1881
1824
|
oAuthLoginSchema,
|
|
1882
|
-
|
|
1883
|
-
otpLoginVerifySchema,
|
|
1884
|
-
parseAuthCookies,
|
|
1825
|
+
parseAuthCookie,
|
|
1885
1826
|
requestPasswordResetSchema,
|
|
1886
1827
|
resetPasswordSchema,
|
|
1887
|
-
|
|
1828
|
+
setAuthCookie,
|
|
1888
1829
|
signupSchema,
|
|
1889
1830
|
twoFaResetSchema,
|
|
1890
|
-
twoFaSetupSchema,
|
|
1891
1831
|
twoFaVerifySchema,
|
|
1892
1832
|
validatePasswordStrength,
|
|
1893
|
-
|
|
1833
|
+
verifyAuthToken,
|
|
1894
1834
|
verifyEmailSchema,
|
|
1895
1835
|
verifyTotp
|
|
1896
1836
|
};
|
package/dist/validators.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import 'zod';
|
|
2
|
-
export {
|
|
2
|
+
export { g as AuthSchemas, C as ChangePasswordInput, h as CreatedSchemas, L as LoginInput, i as LoginSchemaInput, O as OAuthLoginInput, j as OAuthSchemaInput, R as ResetPasswordInput, a as SignupInput, k as SignupSchemaInput, T as TwoFaVerifyInput, V as VerifyEmailInput, b as biometricVerifySchema, c as changePasswordSchema, m as checkPasswordResetSchema, n as createSchemas, p as deregisterPushTokenSchema, q as disableTwofaSchema, e as endAllSessionsSchema, u as getTwofaSecretSchema, l as loginSchema, o as oAuthLoginSchema, w as registerPushTokenSchema, r as requestPasswordResetSchema, d as resetPasswordSchema, s as signupSchema, t as twoFaResetSchema, x as twoFaResetVerifySchema, f as twoFaVerifySchema, v as verifyEmailSchema } from './hooks-BXNxNK4S.mjs';
|
package/dist/validators.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import 'zod';
|
|
2
|
-
export {
|
|
2
|
+
export { g as AuthSchemas, C as ChangePasswordInput, h as CreatedSchemas, L as LoginInput, i as LoginSchemaInput, O as OAuthLoginInput, j as OAuthSchemaInput, R as ResetPasswordInput, a as SignupInput, k as SignupSchemaInput, T as TwoFaVerifyInput, V as VerifyEmailInput, b as biometricVerifySchema, c as changePasswordSchema, m as checkPasswordResetSchema, n as createSchemas, p as deregisterPushTokenSchema, q as disableTwofaSchema, e as endAllSessionsSchema, u as getTwofaSecretSchema, l as loginSchema, o as oAuthLoginSchema, w as registerPushTokenSchema, r as requestPasswordResetSchema, d as resetPasswordSchema, s as signupSchema, t as twoFaResetSchema, x as twoFaResetVerifySchema, f as twoFaVerifySchema, v as verifyEmailSchema } from './hooks-BXNxNK4S.js';
|