@arch-cadre/core 0.0.42 → 0.0.43
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/dist/core/auth/augment.d.ts +18 -0
- package/dist/core/auth/augment.d.ts.map +1 -0
- package/dist/core/auth/augment.js +45 -0
- package/dist/core/auth/email-verification.d.ts +58 -0
- package/dist/core/auth/email-verification.d.ts.map +1 -0
- package/dist/core/auth/email-verification.js +105 -0
- package/dist/core/auth/events.d.ts +53 -0
- package/dist/core/auth/events.d.ts.map +1 -0
- package/dist/core/auth/events.js +1 -0
- package/dist/core/auth/logic.d.ts +106 -0
- package/dist/core/auth/logic.d.ts.map +1 -0
- package/dist/core/auth/logic.js +245 -0
- package/dist/core/auth/password-reset.d.ts +35 -0
- package/dist/core/auth/password-reset.d.ts.map +1 -0
- package/dist/core/auth/password-reset.js +122 -0
- package/dist/core/auth/rbac.d.ts +56 -0
- package/dist/core/auth/rbac.d.ts.map +1 -0
- package/dist/core/auth/rbac.js +134 -0
- package/dist/core/auth/session.d.ts +50 -0
- package/dist/core/auth/session.d.ts.map +1 -0
- package/dist/core/auth/session.js +152 -0
- package/dist/core/auth/types.d.ts +52 -0
- package/dist/core/auth/types.d.ts.map +1 -0
- package/dist/core/auth/types.js +1 -0
- package/dist/core/auth/utils/encode.d.ts +12 -0
- package/dist/core/auth/utils/encode.d.ts.map +1 -0
- package/dist/core/auth/utils/encode.js +20 -0
- package/dist/core/auth/utils/{encryption.d.mts → encryption.d.ts} +5 -8
- package/dist/core/auth/utils/encryption.d.ts.map +1 -0
- package/dist/core/auth/utils/encryption.js +62 -0
- package/dist/core/auth/validation.d.ts +44 -0
- package/dist/core/auth/validation.d.ts.map +1 -0
- package/dist/core/auth/validation.js +41 -0
- package/dist/core/bootstrap.d.ts +2 -0
- package/dist/core/bootstrap.d.ts.map +1 -0
- package/dist/core/bootstrap.js +51 -0
- package/dist/core/config.d.ts +9 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +3 -0
- package/dist/core/config.server.d.ts +12 -0
- package/dist/core/config.server.d.ts.map +1 -0
- package/dist/core/config.server.js +61 -0
- package/dist/core/event-bus.d.ts +14 -0
- package/dist/core/event-bus.d.ts.map +1 -0
- package/dist/core/event-bus.js +51 -0
- package/dist/core/filesystem/index.d.ts +4 -0
- package/dist/core/filesystem/index.d.ts.map +1 -0
- package/dist/core/filesystem/index.js +10 -0
- package/dist/core/filesystem/providers/local.d.ts +8 -0
- package/dist/core/filesystem/providers/local.d.ts.map +1 -0
- package/dist/core/filesystem/providers/local.js +42 -0
- package/dist/core/filesystem/service.d.ts +16 -0
- package/dist/core/filesystem/service.d.ts.map +1 -0
- package/dist/core/filesystem/service.js +51 -0
- package/dist/core/filesystem/types.d.ts +19 -0
- package/dist/core/filesystem/types.d.ts.map +1 -0
- package/dist/core/filesystem/types.js +1 -0
- package/dist/core/notifications/actions.d.ts +54 -0
- package/dist/core/notifications/actions.d.ts.map +1 -0
- package/dist/core/notifications/actions.js +43 -0
- package/dist/core/notifications/index.d.ts +4 -0
- package/dist/core/notifications/index.d.ts.map +1 -0
- package/dist/core/notifications/index.js +3 -0
- package/dist/core/notifications/service.d.ts +7 -0
- package/dist/core/notifications/service.d.ts.map +1 -0
- package/dist/core/notifications/service.js +32 -0
- package/dist/core/notifications/types.d.ts +17 -0
- package/dist/core/notifications/types.d.ts.map +1 -0
- package/dist/core/notifications/types.js +1 -0
- package/dist/core/setup.d.ts +6 -0
- package/dist/core/setup.d.ts.map +1 -0
- package/dist/core/setup.js +25 -0
- package/dist/core/types.d.ts +10 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +16 -0
- package/dist/server/auth/email.d.ts +10 -0
- package/dist/server/auth/email.d.ts.map +1 -0
- package/dist/server/auth/email.js +20 -0
- package/dist/server/auth/{password.d.mts → password.d.ts} +4 -7
- package/dist/server/auth/password.d.ts.map +1 -0
- package/dist/server/auth/password.js +30 -0
- package/dist/server/auth/types.d.ts +13 -0
- package/dist/server/auth/types.d.ts.map +1 -0
- package/dist/server/auth/types.js +1 -0
- package/dist/server/auth/user.d.ts +54 -0
- package/dist/server/auth/user.d.ts.map +1 -0
- package/dist/server/auth/user.js +222 -0
- package/dist/server/database/inject.d.ts +11 -0
- package/dist/server/database/inject.d.ts.map +1 -0
- package/dist/server/database/inject.js +29 -0
- package/dist/server/database/schema.d.ts +2953 -0
- package/dist/server/database/{schema.d.mts.map → schema.d.ts.map} +1 -1
- package/dist/server/database/schema.js +192 -0
- package/dist/server/database/types.d.ts +12 -0
- package/dist/server/database/types.d.ts.map +1 -0
- package/dist/server/database/types.js +1 -0
- package/dist/server/emails/index.d.ts +23 -0
- package/dist/server/emails/index.d.ts.map +1 -0
- package/dist/server/emails/index.js +67 -0
- package/dist/server.d.ts +25 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +32 -0
- package/package.json +5 -6
- package/dist/_virtual/_rolldown/runtime.mjs +0 -1
- package/dist/core/auth/augment.d.mts +0 -20
- package/dist/core/auth/augment.d.mts.map +0 -1
- package/dist/core/auth/augment.mjs +0 -2
- package/dist/core/auth/augment.mjs.map +0 -1
- package/dist/core/auth/email-verification.d.mts +0 -62
- package/dist/core/auth/email-verification.d.mts.map +0 -1
- package/dist/core/auth/email-verification.mjs +0 -2
- package/dist/core/auth/email-verification.mjs.map +0 -1
- package/dist/core/auth/logic.d.mts +0 -110
- package/dist/core/auth/logic.d.mts.map +0 -1
- package/dist/core/auth/logic.mjs +0 -2
- package/dist/core/auth/logic.mjs.map +0 -1
- package/dist/core/auth/password-reset.d.mts +0 -39
- package/dist/core/auth/password-reset.d.mts.map +0 -1
- package/dist/core/auth/password-reset.mjs +0 -2
- package/dist/core/auth/password-reset.mjs.map +0 -1
- package/dist/core/auth/rbac.d.mts +0 -61
- package/dist/core/auth/rbac.d.mts.map +0 -1
- package/dist/core/auth/rbac.mjs +0 -2
- package/dist/core/auth/rbac.mjs.map +0 -1
- package/dist/core/auth/session.d.mts +0 -54
- package/dist/core/auth/session.d.mts.map +0 -1
- package/dist/core/auth/session.mjs +0 -2
- package/dist/core/auth/session.mjs.map +0 -1
- package/dist/core/auth/types.d.mts +0 -55
- package/dist/core/auth/types.d.mts.map +0 -1
- package/dist/core/auth/utils/encode.d.mts +0 -15
- package/dist/core/auth/utils/encode.d.mts.map +0 -1
- package/dist/core/auth/utils/encode.mjs +0 -2
- package/dist/core/auth/utils/encode.mjs.map +0 -1
- package/dist/core/auth/utils/encryption.d.mts.map +0 -1
- package/dist/core/auth/utils/encryption.mjs +0 -2
- package/dist/core/auth/utils/encryption.mjs.map +0 -1
- package/dist/core/auth/validation.d.mts +0 -48
- package/dist/core/auth/validation.d.mts.map +0 -1
- package/dist/core/auth/validation.mjs +0 -2
- package/dist/core/auth/validation.mjs.map +0 -1
- package/dist/core/bootstrap.d.mts +0 -5
- package/dist/core/bootstrap.d.mts.map +0 -1
- package/dist/core/bootstrap.mjs +0 -2
- package/dist/core/bootstrap.mjs.map +0 -1
- package/dist/core/config.d.mts +0 -11
- package/dist/core/config.d.mts.map +0 -1
- package/dist/core/config.mjs +0 -2
- package/dist/core/config.mjs.map +0 -1
- package/dist/core/config.server.d.mts +0 -16
- package/dist/core/config.server.d.mts.map +0 -1
- package/dist/core/config.server.mjs +0 -2
- package/dist/core/config.server.mjs.map +0 -1
- package/dist/core/event-bus.d.mts +0 -17
- package/dist/core/event-bus.d.mts.map +0 -1
- package/dist/core/event-bus.mjs +0 -2
- package/dist/core/event-bus.mjs.map +0 -1
- package/dist/core/filesystem/index.mjs +0 -2
- package/dist/core/filesystem/index.mjs.map +0 -1
- package/dist/core/filesystem/providers/local.mjs +0 -2
- package/dist/core/filesystem/providers/local.mjs.map +0 -1
- package/dist/core/filesystem/service.d.mts +0 -19
- package/dist/core/filesystem/service.d.mts.map +0 -1
- package/dist/core/filesystem/service.mjs +0 -2
- package/dist/core/filesystem/service.mjs.map +0 -1
- package/dist/core/filesystem/types.d.mts +0 -22
- package/dist/core/filesystem/types.d.mts.map +0 -1
- package/dist/core/notifications/actions.d.mts +0 -58
- package/dist/core/notifications/actions.d.mts.map +0 -1
- package/dist/core/notifications/actions.mjs +0 -2
- package/dist/core/notifications/actions.mjs.map +0 -1
- package/dist/core/notifications/index.mjs +0 -1
- package/dist/core/notifications/service.d.mts +0 -9
- package/dist/core/notifications/service.d.mts.map +0 -1
- package/dist/core/notifications/service.mjs +0 -2
- package/dist/core/notifications/service.mjs.map +0 -1
- package/dist/core/notifications/types.d.mts +0 -21
- package/dist/core/notifications/types.d.mts.map +0 -1
- package/dist/core/setup.d.mts +0 -9
- package/dist/core/setup.d.mts.map +0 -1
- package/dist/core/setup.mjs +0 -2
- package/dist/core/setup.mjs.map +0 -1
- package/dist/core/types.d.mts +0 -13
- package/dist/core/types.d.mts.map +0 -1
- package/dist/index.d.mts +0 -8
- package/dist/index.mjs +0 -1
- package/dist/server/auth/email.d.mts +0 -13
- package/dist/server/auth/email.d.mts.map +0 -1
- package/dist/server/auth/email.mjs +0 -2
- package/dist/server/auth/email.mjs.map +0 -1
- package/dist/server/auth/password.d.mts.map +0 -1
- package/dist/server/auth/password.mjs +0 -2
- package/dist/server/auth/password.mjs.map +0 -1
- package/dist/server/auth/user.d.mts +0 -58
- package/dist/server/auth/user.d.mts.map +0 -1
- package/dist/server/auth/user.mjs +0 -2
- package/dist/server/auth/user.mjs.map +0 -1
- package/dist/server/database/inject.d.mts +0 -15
- package/dist/server/database/inject.d.mts.map +0 -1
- package/dist/server/database/inject.mjs +0 -2
- package/dist/server/database/inject.mjs.map +0 -1
- package/dist/server/database/schema.d.mts +0 -2962
- package/dist/server/database/schema.mjs +0 -2
- package/dist/server/database/schema.mjs.map +0 -1
- package/dist/server/emails/index.d.mts +0 -26
- package/dist/server/emails/index.d.mts.map +0 -1
- package/dist/server/emails/index.mjs +0 -2
- package/dist/server/emails/index.mjs.map +0 -1
- package/dist/server.d.mts +0 -26
- package/dist/server.mjs +0 -1
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { FullUser, PasswordResetSession, Session, User } from "./types";
|
|
2
|
+
/**
|
|
3
|
+
* REGISTRIES FOR MODULAR EXTENSIONS
|
|
4
|
+
*/
|
|
5
|
+
type IdentityAugmenter = (user: User) => Promise<Partial<FullUser>>;
|
|
6
|
+
type SessionAugmenter = (session: Session) => Promise<Partial<Session>>;
|
|
7
|
+
type PasswordResetSessionAugmenter = (session: PasswordResetSession) => Promise<Partial<PasswordResetSession>>;
|
|
8
|
+
export declare function registerIdentityAugmenter(augmenter: IdentityAugmenter): void;
|
|
9
|
+
export declare function registerSessionAugmenter(augmenter: SessionAugmenter): void;
|
|
10
|
+
export declare function registerPasswordResetSessionAugmenter(augmenter: PasswordResetSessionAugmenter): void;
|
|
11
|
+
/**
|
|
12
|
+
* EXECUTION FUNCTIONS
|
|
13
|
+
*/
|
|
14
|
+
export declare function augmentUser(user: User, coreRbacData?: Record<string, any>): Promise<FullUser>;
|
|
15
|
+
export declare function augmentSession(session: Session): Promise<Session>;
|
|
16
|
+
export declare function augmentPasswordResetSession(session: PasswordResetSession): Promise<PasswordResetSession>;
|
|
17
|
+
export {};
|
|
18
|
+
//# sourceMappingURL=augment.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"augment.d.ts","sourceRoot":"","sources":["../../../src/core/auth/augment.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,oBAAoB,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAE7E;;GAEG;AAEH,KAAK,iBAAiB,GAAG,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;AACpE,KAAK,gBAAgB,GAAG,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC;AACxE,KAAK,6BAA6B,GAAG,CACnC,OAAO,EAAE,oBAAoB,KAC1B,OAAO,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC,CAAC;AAuB5C,wBAAgB,yBAAyB,CAAC,SAAS,EAAE,iBAAiB,QAErE;AAED,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,gBAAgB,QAEnE;AAED,wBAAgB,qCAAqC,CACnD,SAAS,EAAE,6BAA6B,QAGzC;AAED;;GAEG;AACH,wBAAsB,WAAW,CAC/B,IAAI,EAAE,IAAI,EACV,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GACjC,OAAO,CAAC,QAAQ,CAAC,CAOnB;AAED,wBAAsB,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAOvE;AAED,wBAAsB,2BAA2B,CAC/C,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,oBAAoB,CAAC,CAO/B"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
var _a, _b, _c;
|
|
2
|
+
const globalForAugment = globalThis;
|
|
3
|
+
const identityAugmenters = (_a = globalForAugment.__KRYO_IDENTITY_AUGMENTERS__) !== null && _a !== void 0 ? _a : new Set();
|
|
4
|
+
const sessionAugmenters = (_b = globalForAugment.__KRYO_SESSION_AUGMENTERS__) !== null && _b !== void 0 ? _b : new Set();
|
|
5
|
+
const passwordResetSessionAugmenters = (_c = globalForAugment.__KRYO_PASSWORD_RESET_SESSION_AUGMENTERS__) !== null && _c !== void 0 ? _c : new Set();
|
|
6
|
+
globalForAugment.__KRYO_IDENTITY_AUGMENTERS__ = identityAugmenters;
|
|
7
|
+
globalForAugment.__KRYO_SESSION_AUGMENTERS__ = sessionAugmenters;
|
|
8
|
+
globalForAugment.__KRYO_PASSWORD_RESET_SESSION_AUGMENTERS__ =
|
|
9
|
+
passwordResetSessionAugmenters;
|
|
10
|
+
export function registerIdentityAugmenter(augmenter) {
|
|
11
|
+
identityAugmenters.add(augmenter);
|
|
12
|
+
}
|
|
13
|
+
export function registerSessionAugmenter(augmenter) {
|
|
14
|
+
sessionAugmenters.add(augmenter);
|
|
15
|
+
}
|
|
16
|
+
export function registerPasswordResetSessionAugmenter(augmenter) {
|
|
17
|
+
passwordResetSessionAugmenters.add(augmenter);
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* EXECUTION FUNCTIONS
|
|
21
|
+
*/
|
|
22
|
+
export async function augmentUser(user, coreRbacData) {
|
|
23
|
+
let augmentedData = coreRbacData || {};
|
|
24
|
+
for (const augmenter of identityAugmenters) {
|
|
25
|
+
const data = await augmenter(user);
|
|
26
|
+
augmentedData = { ...augmentedData, ...data };
|
|
27
|
+
}
|
|
28
|
+
return { ...user, ...augmentedData };
|
|
29
|
+
}
|
|
30
|
+
export async function augmentSession(session) {
|
|
31
|
+
let augmentedData = {};
|
|
32
|
+
for (const augmenter of sessionAugmenters) {
|
|
33
|
+
const data = await augmenter(session);
|
|
34
|
+
augmentedData = { ...augmentedData, ...data };
|
|
35
|
+
}
|
|
36
|
+
return { ...session, ...augmentedData };
|
|
37
|
+
}
|
|
38
|
+
export async function augmentPasswordResetSession(session) {
|
|
39
|
+
let augmentedData = {};
|
|
40
|
+
for (const augmenter of passwordResetSessionAugmenters) {
|
|
41
|
+
const data = await augmenter(session);
|
|
42
|
+
augmentedData = { ...augmentedData, ...data };
|
|
43
|
+
}
|
|
44
|
+
return { ...session, ...augmentedData };
|
|
45
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { emailVerificationTable } from "../../server/database/schema";
|
|
2
|
+
/**
|
|
3
|
+
* Register Email Verification as a Core Security Requirement.
|
|
4
|
+
*/
|
|
5
|
+
export declare function initEmailVerification(): Promise<void>;
|
|
6
|
+
/**
|
|
7
|
+
* Retrieves a specific email verification request for a user.
|
|
8
|
+
*/
|
|
9
|
+
export declare function getUserEmailVerificationRequest(userId: string, id: string): Promise<{
|
|
10
|
+
id: string;
|
|
11
|
+
email: string;
|
|
12
|
+
code: string;
|
|
13
|
+
userId: string;
|
|
14
|
+
expiresAt: Date;
|
|
15
|
+
createdAt: Date;
|
|
16
|
+
updatedAt: Date | null;
|
|
17
|
+
}>;
|
|
18
|
+
/**
|
|
19
|
+
* Creates a new email verification request, deleting any existing one for the user.
|
|
20
|
+
*/
|
|
21
|
+
export declare function createEmailVerificationRequest(userId: string, email: string): Promise<{
|
|
22
|
+
id: string;
|
|
23
|
+
email: string;
|
|
24
|
+
createdAt: Date;
|
|
25
|
+
updatedAt: Date | null;
|
|
26
|
+
userId: string;
|
|
27
|
+
expiresAt: Date;
|
|
28
|
+
code: string;
|
|
29
|
+
}>;
|
|
30
|
+
/**
|
|
31
|
+
* Deletes all email verification requests for a user.
|
|
32
|
+
*/
|
|
33
|
+
export declare function deleteUserEmailVerificationRequest(userId: string): Promise<void>;
|
|
34
|
+
/**
|
|
35
|
+
* Sends a verification email with the OTP code.
|
|
36
|
+
*/
|
|
37
|
+
export declare function sendVerificationEmail(email: string, code: string): Promise<void>;
|
|
38
|
+
/**
|
|
39
|
+
* Sets the email verification request ID in a cookie.
|
|
40
|
+
*/
|
|
41
|
+
export declare function setEmailVerificationRequestCookie(request: typeof emailVerificationTable.$inferSelect): Promise<void>;
|
|
42
|
+
/**
|
|
43
|
+
* Removes the email verification request cookie.
|
|
44
|
+
*/
|
|
45
|
+
export declare function deleteEmailVerificationRequestCookie(): Promise<void>;
|
|
46
|
+
/**
|
|
47
|
+
* Retrieves the current email verification request based on session and cookie.
|
|
48
|
+
*/
|
|
49
|
+
export declare function getUserEmailVerificationRequestFromRequest(): Promise<{
|
|
50
|
+
id: string;
|
|
51
|
+
email: string;
|
|
52
|
+
code: string;
|
|
53
|
+
userId: string;
|
|
54
|
+
expiresAt: Date;
|
|
55
|
+
createdAt: Date;
|
|
56
|
+
updatedAt: Date | null;
|
|
57
|
+
} | null>;
|
|
58
|
+
//# sourceMappingURL=email-verification.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"email-verification.d.ts","sourceRoot":"","sources":["../../../src/core/auth/email-verification.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AAMtE;;GAEG;AACH,wBAAsB,qBAAqB,kBAU1C;AAED;;GAEG;AACH,wBAAsB,+BAA+B,CACnD,MAAM,EAAE,MAAM,EACd,EAAE,EAAE,MAAM;;;;;;;;GAaX;AAED;;GAEG;AACH,wBAAsB,8BAA8B,CAClD,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM;;;;;;;;GAiBd;AAED;;GAEG;AACH,wBAAsB,kCAAkC,CACtD,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,IAAI,CAAC,CAIf;AAED;;GAEG;AACH,wBAAsB,qBAAqB,CACzC,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,IAAI,CAAC,CAEf;AAED;;GAEG;AACH,wBAAsB,iCAAiC,CACrD,OAAO,EAAE,OAAO,sBAAsB,CAAC,YAAY,GAClD,OAAO,CAAC,IAAI,CAAC,CAUf;AAED;;GAEG;AACH,wBAAsB,oCAAoC,IAAI,OAAO,CAAC,IAAI,CAAC,CAG1E;AAED;;GAEG;AACH,wBAAsB,0CAA0C;;;;;;;;UAqB/D"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
"use server";
|
|
2
|
+
import { addHours } from "date-fns";
|
|
3
|
+
import { and, eq } from "drizzle-orm";
|
|
4
|
+
import { cookies } from "next/headers";
|
|
5
|
+
import { db } from "../../server/database/inject";
|
|
6
|
+
import { emailVerificationTable } from "../../server/database/schema";
|
|
7
|
+
import { sendVerifyEmail } from "../../server/emails/index";
|
|
8
|
+
import { registerSecurityRequirement } from "./logic";
|
|
9
|
+
import { getCurrentSession } from "./session";
|
|
10
|
+
import { generateRandomOTP } from "./utils/encode";
|
|
11
|
+
/**
|
|
12
|
+
* Register Email Verification as a Core Security Requirement.
|
|
13
|
+
*/
|
|
14
|
+
export async function initEmailVerification() {
|
|
15
|
+
registerSecurityRequirement(async (_session, user) => {
|
|
16
|
+
if (!user.emailVerifiedAt) {
|
|
17
|
+
return {
|
|
18
|
+
satisfied: false,
|
|
19
|
+
redirect: "/verify-email?unverified",
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
return { satisfied: true };
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Retrieves a specific email verification request for a user.
|
|
27
|
+
*/
|
|
28
|
+
export async function getUserEmailVerificationRequest(userId, id) {
|
|
29
|
+
const [session] = await db
|
|
30
|
+
.select()
|
|
31
|
+
.from(emailVerificationTable)
|
|
32
|
+
.where(and(eq(emailVerificationTable.id, id), eq(emailVerificationTable.userId, userId)));
|
|
33
|
+
return session;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Creates a new email verification request, deleting any existing one for the user.
|
|
37
|
+
*/
|
|
38
|
+
export async function createEmailVerificationRequest(userId, email) {
|
|
39
|
+
await deleteUserEmailVerificationRequest(userId);
|
|
40
|
+
const code = generateRandomOTP();
|
|
41
|
+
const [verificationRequest] = await db
|
|
42
|
+
.insert(emailVerificationTable)
|
|
43
|
+
.values({
|
|
44
|
+
userId,
|
|
45
|
+
code,
|
|
46
|
+
email,
|
|
47
|
+
expiresAt: new Date(addHours(new Date(), 1)),
|
|
48
|
+
})
|
|
49
|
+
.returning();
|
|
50
|
+
return verificationRequest;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Deletes all email verification requests for a user.
|
|
54
|
+
*/
|
|
55
|
+
export async function deleteUserEmailVerificationRequest(userId) {
|
|
56
|
+
await db
|
|
57
|
+
.delete(emailVerificationTable)
|
|
58
|
+
.where(eq(emailVerificationTable.userId, userId));
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Sends a verification email with the OTP code.
|
|
62
|
+
*/
|
|
63
|
+
export async function sendVerificationEmail(email, code) {
|
|
64
|
+
await sendVerifyEmail(email, code);
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Sets the email verification request ID in a cookie.
|
|
68
|
+
*/
|
|
69
|
+
export async function setEmailVerificationRequestCookie(request) {
|
|
70
|
+
const cookieStore = await cookies();
|
|
71
|
+
cookieStore.set("email_verification", request.id, {
|
|
72
|
+
httpOnly: true,
|
|
73
|
+
path: "/",
|
|
74
|
+
secure: process.env.NODE_ENV === "production",
|
|
75
|
+
sameSite: "lax",
|
|
76
|
+
expires: request.expiresAt,
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Removes the email verification request cookie.
|
|
81
|
+
*/
|
|
82
|
+
export async function deleteEmailVerificationRequestCookie() {
|
|
83
|
+
const cookieStore = await cookies();
|
|
84
|
+
cookieStore.delete("email_verification");
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Retrieves the current email verification request based on session and cookie.
|
|
88
|
+
*/
|
|
89
|
+
export async function getUserEmailVerificationRequestFromRequest() {
|
|
90
|
+
var _a, _b;
|
|
91
|
+
const { user } = await getCurrentSession();
|
|
92
|
+
if (!user) {
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
const cookieStore = await cookies();
|
|
96
|
+
const id = (_b = (_a = cookieStore.get("email_verification")) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : null;
|
|
97
|
+
if (!id) {
|
|
98
|
+
return null;
|
|
99
|
+
}
|
|
100
|
+
const request = await getUserEmailVerificationRequest(user.id, id);
|
|
101
|
+
if (!request) {
|
|
102
|
+
await deleteEmailVerificationRequestCookie();
|
|
103
|
+
}
|
|
104
|
+
return request;
|
|
105
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { Session, User } from "./types";
|
|
2
|
+
export type AuthEventPayloads = {
|
|
3
|
+
/**
|
|
4
|
+
* Emitted after password/base credentials are verified,
|
|
5
|
+
* but BEFORE the final session is created.
|
|
6
|
+
* Listeners can return a "veto" to require additional factors.
|
|
7
|
+
*/
|
|
8
|
+
"auth:validate-factors": {
|
|
9
|
+
userId: string;
|
|
10
|
+
email: string;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Emitted after a full session is successfully created.
|
|
14
|
+
*/
|
|
15
|
+
"auth:session-created": {
|
|
16
|
+
session: Session;
|
|
17
|
+
user: User;
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Emitted after a user signs out.
|
|
21
|
+
*/
|
|
22
|
+
"auth:signed-out": {
|
|
23
|
+
userId: string;
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Emitted when a password reset is requested.
|
|
27
|
+
*/
|
|
28
|
+
"auth:password-reset:requested": {
|
|
29
|
+
userId: string;
|
|
30
|
+
email: string;
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Emitted when a password has been successfully reset.
|
|
34
|
+
*/
|
|
35
|
+
"auth:password-reset:completed": {
|
|
36
|
+
userId: string;
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* Emitted when a verification email is sent.
|
|
40
|
+
*/
|
|
41
|
+
"auth:verification-requested": {
|
|
42
|
+
userId: string;
|
|
43
|
+
email: string;
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* Emitted when a user successfully verifies their email.
|
|
47
|
+
*/
|
|
48
|
+
"auth:email-verified": {
|
|
49
|
+
userId: string;
|
|
50
|
+
email: string;
|
|
51
|
+
};
|
|
52
|
+
};
|
|
53
|
+
//# sourceMappingURL=events.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../../src/core/auth/events.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAE7C,MAAM,MAAM,iBAAiB,GAAG;IAC9B;;;;OAIG;IACH,uBAAuB,EAAE;QACvB,MAAM,EAAE,MAAM,CAAC;QACf,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;IAEF;;OAEG;IACH,sBAAsB,EAAE;QACtB,OAAO,EAAE,OAAO,CAAC;QACjB,IAAI,EAAE,IAAI,CAAC;KACZ,CAAC;IAEF;;OAEG;IACH,iBAAiB,EAAE;QACjB,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;IAEF;;OAEG;IACH,+BAA+B,EAAE;QAC/B,MAAM,EAAE,MAAM,CAAC;QACf,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;IAEF;;OAEG;IACH,+BAA+B,EAAE;QAC/B,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;IAEF;;OAEG;IACH,6BAA6B,EAAE;QAC7B,MAAM,EAAE,MAAM,CAAC;QACf,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;IAEF;;OAEG;IACH,qBAAqB,EAAE;QACrB,MAAM,EAAE,MAAM,CAAC;QACf,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;CACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { augmentSession, augmentUser, registerIdentityAugmenter, registerPasswordResetSessionAugmenter, registerSessionAugmenter } from "./augment";
|
|
2
|
+
import type { AuthResponse, FullUser, Session, SessionFlags, User, UserPermission, UserRole } from "./types";
|
|
3
|
+
import { type LoginInput, type RegisterInput } from "./validation";
|
|
4
|
+
/**
|
|
5
|
+
* Registry for login validators (e.g. 2FA module)
|
|
6
|
+
*/
|
|
7
|
+
type AuthValidator = (userId: string) => Promise<AuthResponse | null>;
|
|
8
|
+
/**
|
|
9
|
+
* Registry for Security Requirements (e.g. checking if 2FA is needed for a session)
|
|
10
|
+
*/
|
|
11
|
+
type SecurityRequirement = (session: Session, user: FullUser) => Promise<{
|
|
12
|
+
satisfied: boolean;
|
|
13
|
+
redirect?: string;
|
|
14
|
+
} | null>;
|
|
15
|
+
/**
|
|
16
|
+
* Registry for password reset validators (e.g. 2FA module requiring check during reset)
|
|
17
|
+
*/
|
|
18
|
+
type PasswordResetValidator = (userId: string) => Promise<AuthResponse | null>;
|
|
19
|
+
/**
|
|
20
|
+
* Registry for email verification validators
|
|
21
|
+
*/
|
|
22
|
+
type EmailVerificationValidator = (userId: string) => Promise<AuthResponse | null>;
|
|
23
|
+
export declare function registerAuthValidator(validator: AuthValidator): Promise<void>;
|
|
24
|
+
export declare function registerPasswordResetValidator(validator: PasswordResetValidator): Promise<void>;
|
|
25
|
+
export declare function registerEmailVerificationValidator(validator: EmailVerificationValidator): Promise<void>;
|
|
26
|
+
export { registerIdentityAugmenter, registerSessionAugmenter, registerPasswordResetSessionAugmenter, augmentUser, augmentSession, };
|
|
27
|
+
export declare function registerSecurityRequirement(requirement: SecurityRequirement): Promise<void>;
|
|
28
|
+
export declare function runPasswordResetValidators(userId: string): Promise<AuthResponse | null>;
|
|
29
|
+
export declare function runEmailVerificationValidators(userId: string): Promise<AuthResponse | null>;
|
|
30
|
+
/**
|
|
31
|
+
* Augments a base user with data from all registered modules.
|
|
32
|
+
* This is now just a wrapper that includes core RBAC data.
|
|
33
|
+
*/
|
|
34
|
+
export declare function performFullUserAugmentation(user: User): Promise<FullUser>;
|
|
35
|
+
/**
|
|
36
|
+
* Checks if the current session satisfies all registered security requirements.
|
|
37
|
+
*/
|
|
38
|
+
export declare function checkSecurity(session: Session, user: FullUser, requiredRoles?: UserRole[], requiredPermissions?: UserPermission[], fallbackRedirect?: string): Promise<{
|
|
39
|
+
satisfied: boolean;
|
|
40
|
+
redirect: string | undefined;
|
|
41
|
+
} | {
|
|
42
|
+
satisfied: boolean;
|
|
43
|
+
redirect?: undefined;
|
|
44
|
+
}>;
|
|
45
|
+
/**
|
|
46
|
+
* Sign In Logic
|
|
47
|
+
*/
|
|
48
|
+
export declare function signIn(data: LoginInput): Promise<AuthResponse>;
|
|
49
|
+
/**
|
|
50
|
+
* Sign Up Logic
|
|
51
|
+
*/
|
|
52
|
+
export declare function signUp(data: RegisterInput): Promise<{
|
|
53
|
+
session: {
|
|
54
|
+
[x: string]: any;
|
|
55
|
+
id: string;
|
|
56
|
+
createdAt: Date;
|
|
57
|
+
updatedAt: Date | null;
|
|
58
|
+
userId: string;
|
|
59
|
+
active_organization_id: string | null;
|
|
60
|
+
expiresAt: Date;
|
|
61
|
+
};
|
|
62
|
+
user: {
|
|
63
|
+
[x: string]: any;
|
|
64
|
+
id: string;
|
|
65
|
+
email: string;
|
|
66
|
+
name: string;
|
|
67
|
+
password: string | null;
|
|
68
|
+
image: string | null;
|
|
69
|
+
recovery_code: Buffer<ArrayBufferLike>;
|
|
70
|
+
emailVerifiedAt: Date | null;
|
|
71
|
+
createdAt: Date;
|
|
72
|
+
updatedAt: Date | null;
|
|
73
|
+
roles: UserRole[];
|
|
74
|
+
permissions: UserPermission[];
|
|
75
|
+
};
|
|
76
|
+
}>;
|
|
77
|
+
/**
|
|
78
|
+
* Finalizes login after a challenge
|
|
79
|
+
*/
|
|
80
|
+
export declare function finalizeLogin(userId: string, flags: SessionFlags): Promise<{
|
|
81
|
+
session: {
|
|
82
|
+
[x: string]: any;
|
|
83
|
+
id: string;
|
|
84
|
+
createdAt: Date;
|
|
85
|
+
updatedAt: Date | null;
|
|
86
|
+
userId: string;
|
|
87
|
+
active_organization_id: string | null;
|
|
88
|
+
expiresAt: Date;
|
|
89
|
+
} | null;
|
|
90
|
+
user: {
|
|
91
|
+
id: string;
|
|
92
|
+
email: string;
|
|
93
|
+
name: string;
|
|
94
|
+
password: string | null;
|
|
95
|
+
image: string | null;
|
|
96
|
+
recovery_code: Buffer<ArrayBufferLike>;
|
|
97
|
+
emailVerifiedAt: Date | null;
|
|
98
|
+
createdAt: Date;
|
|
99
|
+
updatedAt: Date | null;
|
|
100
|
+
} | null;
|
|
101
|
+
}>;
|
|
102
|
+
/**
|
|
103
|
+
* Sign Out
|
|
104
|
+
*/
|
|
105
|
+
export declare function signOut(): Promise<void>;
|
|
106
|
+
//# sourceMappingURL=logic.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logic.d.ts","sourceRoot":"","sources":["../../../src/core/auth/logic.ts"],"names":[],"mappings":"AAuBA,OAAO,EACL,cAAc,EACd,WAAW,EACX,yBAAyB,EACzB,qCAAqC,EACrC,wBAAwB,EACzB,MAAM,WAAW,CAAC;AAcnB,OAAO,KAAK,EACV,YAAY,EACZ,QAAQ,EACR,OAAO,EACP,YAAY,EACZ,IAAI,EACJ,cAAc,EACd,QAAQ,EACT,MAAM,SAAS,CAAC;AACjB,OAAO,EACL,KAAK,UAAU,EAEf,KAAK,aAAa,EAEnB,MAAM,cAAc,CAAC;AA6DtB;;GAEG;AACH,KAAK,aAAa,GAAG,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAAC;AAEtE;;GAEG;AACH,KAAK,mBAAmB,GAAG,CACzB,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,QAAQ,KACX,OAAO,CAAC;IAAE,SAAS,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,CAAC;AAE/D;;GAEG;AACH,KAAK,sBAAsB,GAAG,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAAC;AAE/E;;GAEG;AACH,KAAK,0BAA0B,GAAG,CAChC,MAAM,EAAE,MAAM,KACX,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAAC;AA6BlC,wBAAsB,qBAAqB,CAAC,SAAS,EAAE,aAAa,iBAEnE;AAED,wBAAsB,8BAA8B,CAClD,SAAS,EAAE,sBAAsB,iBAGlC;AAED,wBAAsB,kCAAkC,CACtD,SAAS,EAAE,0BAA0B,iBAGtC;AAED,OAAO,EACL,yBAAyB,EACzB,wBAAwB,EACxB,qCAAqC,EACrC,WAAW,EACX,cAAc,GACf,CAAC;AAEF,wBAAsB,2BAA2B,CAC/C,WAAW,EAAE,mBAAmB,iBAGjC;AAED,wBAAsB,0BAA0B,CAC9C,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAM9B;AAED,wBAAsB,8BAA8B,CAClD,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAM9B;AAED;;;GAGG;AACH,wBAAsB,2BAA2B,CAC/C,IAAI,EAAE,IAAI,GACT,OAAO,CAAC,QAAQ,CAAC,CAGnB;AAED;;GAEG;AACH,wBAAsB,aAAa,CACjC,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,QAAQ,EACd,aAAa,CAAC,EAAE,QAAQ,EAAE,EAC1B,mBAAmB,CAAC,EAAE,cAAc,EAAE,EACtC,gBAAgB,CAAC,EAAE,MAAM;;;;;;GA0D1B;AAED;;GAEG;AACH,wBAAsB,MAAM,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,YAAY,CAAC,CAgCpE;AAED;;GAEG;AACH,wBAAsB,MAAM,CAAC,IAAI,EAAE,aAAa;;;;;;;;;;;;;;;;;;;;;;;;GAmC/C;AAED;;GAEG;AACH,wBAAsB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY;;;;;;;;;;;;;;;;;;;;;GAetE;AAED;;GAEG;AACH,wBAAsB,OAAO,kBAS5B"}
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
"use server";
|
|
2
|
+
var _a, _b, _c, _d;
|
|
3
|
+
import { eq, inArray } from "drizzle-orm";
|
|
4
|
+
import { verifyPasswordHash, verifyPasswordStrength, } from "../../server/auth/password";
|
|
5
|
+
import { createUser, getUserById, getUserFromEmail, getUserPasswordHash, verifyUsernameInput, } from "../../server/auth/user";
|
|
6
|
+
import { db } from "../../server/database/inject";
|
|
7
|
+
import { permissionsTable, rolesTable, rolesToPermissionsTable, usersToPermissionsTable, usersToRolesTable, } from "../../server/database/schema";
|
|
8
|
+
import { eventBus } from "../event-bus";
|
|
9
|
+
import { augmentSession, augmentUser, registerIdentityAugmenter, registerPasswordResetSessionAugmenter, registerSessionAugmenter, } from "./augment";
|
|
10
|
+
import { createEmailVerificationRequest, sendVerificationEmail, setEmailVerificationRequestCookie, } from "./email-verification";
|
|
11
|
+
import { createSession, deleteSessionTokenCookie, generateSessionToken, getCurrentSession, invalidateSession, setSessionTokenCookie, } from "./session";
|
|
12
|
+
import { loginSchema, registerSchema, } from "./validation";
|
|
13
|
+
/**
|
|
14
|
+
* Podstawowy moduł rozszerzający tożsamość dla ról i uprawnień
|
|
15
|
+
*/
|
|
16
|
+
async function coreRbacAugmenter(user) {
|
|
17
|
+
try {
|
|
18
|
+
// 1. Fetch direct roles
|
|
19
|
+
const userRoles = await db
|
|
20
|
+
.select({ name: rolesTable.name })
|
|
21
|
+
.from(usersToRolesTable)
|
|
22
|
+
.innerJoin(rolesTable, eq(usersToRolesTable.roleId, rolesTable.id))
|
|
23
|
+
.where(eq(usersToRolesTable.userId, user.id));
|
|
24
|
+
const roles = userRoles.map((r) => r.name);
|
|
25
|
+
// 2. Fetch direct permissions
|
|
26
|
+
const userDirectPerms = await db
|
|
27
|
+
.select({ name: permissionsTable.name })
|
|
28
|
+
.from(usersToPermissionsTable)
|
|
29
|
+
.innerJoin(permissionsTable, eq(usersToPermissionsTable.permissionId, permissionsTable.id))
|
|
30
|
+
.where(eq(usersToPermissionsTable.userId, user.id));
|
|
31
|
+
const directPerms = userDirectPerms.map((p) => p.name);
|
|
32
|
+
// 3. Fetch permissions from roles
|
|
33
|
+
let rolePerms = [];
|
|
34
|
+
if (roles.length > 0) {
|
|
35
|
+
const roleIdsResult = await db
|
|
36
|
+
.select({ id: rolesTable.id })
|
|
37
|
+
.from(rolesTable)
|
|
38
|
+
.where(inArray(rolesTable.name, roles));
|
|
39
|
+
const roleIds = roleIdsResult.map((r) => r.id);
|
|
40
|
+
if (roleIds.length > 0) {
|
|
41
|
+
const rolePermsData = await db
|
|
42
|
+
.select({ name: permissionsTable.name })
|
|
43
|
+
.from(rolesToPermissionsTable)
|
|
44
|
+
.innerJoin(permissionsTable, eq(rolesToPermissionsTable.permissionId, permissionsTable.id))
|
|
45
|
+
.where(inArray(rolesToPermissionsTable.roleId, roleIds));
|
|
46
|
+
rolePerms = rolePermsData.map((p) => p.name);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return {
|
|
50
|
+
roles,
|
|
51
|
+
permissions: Array.from(new Set([...directPerms, ...rolePerms])),
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
catch (error) {
|
|
55
|
+
console.error("[Auth:RBAC] Failed to augment user:", error);
|
|
56
|
+
return { roles: [], permissions: [] };
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
const globalForAuth = globalThis;
|
|
60
|
+
const authValidators = (_a = globalForAuth.__KRYO_AUTH_VALIDATORS__) !== null && _a !== void 0 ? _a : new Set();
|
|
61
|
+
const securityRequirements = (_b = globalForAuth.__KRYO_SECURITY_REQUIREMENTS__) !== null && _b !== void 0 ? _b : new Set();
|
|
62
|
+
const passwordResetValidators = (_c = globalForAuth.__KRYO_PASSWORD_RESET_VALIDATORS__) !== null && _c !== void 0 ? _c : new Set();
|
|
63
|
+
const emailVerificationValidators = (_d = globalForAuth.__KRYO_EMAIL_VERIFICATION_VALIDATORS__) !== null && _d !== void 0 ? _d : new Set();
|
|
64
|
+
globalForAuth.__KRYO_AUTH_VALIDATORS__ = authValidators;
|
|
65
|
+
globalForAuth.__KRYO_SECURITY_REQUIREMENTS__ = securityRequirements;
|
|
66
|
+
globalForAuth.__KRYO_PASSWORD_RESET_VALIDATORS__ = passwordResetValidators;
|
|
67
|
+
globalForAuth.__KRYO_EMAIL_VERIFICATION_VALIDATORS__ =
|
|
68
|
+
emailVerificationValidators;
|
|
69
|
+
export async function registerAuthValidator(validator) {
|
|
70
|
+
authValidators.add(validator);
|
|
71
|
+
}
|
|
72
|
+
export async function registerPasswordResetValidator(validator) {
|
|
73
|
+
passwordResetValidators.add(validator);
|
|
74
|
+
}
|
|
75
|
+
export async function registerEmailVerificationValidator(validator) {
|
|
76
|
+
emailVerificationValidators.add(validator);
|
|
77
|
+
}
|
|
78
|
+
export { registerIdentityAugmenter, registerSessionAugmenter, registerPasswordResetSessionAugmenter, augmentUser, augmentSession, };
|
|
79
|
+
export async function registerSecurityRequirement(requirement) {
|
|
80
|
+
securityRequirements.add(requirement);
|
|
81
|
+
}
|
|
82
|
+
export async function runPasswordResetValidators(userId) {
|
|
83
|
+
for (const validator of passwordResetValidators) {
|
|
84
|
+
const interception = await validator(userId);
|
|
85
|
+
if (interception)
|
|
86
|
+
return interception;
|
|
87
|
+
}
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
export async function runEmailVerificationValidators(userId) {
|
|
91
|
+
for (const validator of emailVerificationValidators) {
|
|
92
|
+
const interception = await validator(userId);
|
|
93
|
+
if (interception)
|
|
94
|
+
return interception;
|
|
95
|
+
}
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Augments a base user with data from all registered modules.
|
|
100
|
+
* This is now just a wrapper that includes core RBAC data.
|
|
101
|
+
*/
|
|
102
|
+
export async function performFullUserAugmentation(user) {
|
|
103
|
+
const coreRbacData = await coreRbacAugmenter(user);
|
|
104
|
+
return await augmentUser(user, coreRbacData);
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Checks if the current session satisfies all registered security requirements.
|
|
108
|
+
*/
|
|
109
|
+
export async function checkSecurity(session, user, requiredRoles, requiredPermissions, fallbackRedirect) {
|
|
110
|
+
var _a;
|
|
111
|
+
if (!user) {
|
|
112
|
+
console.warn("User is required for security check");
|
|
113
|
+
return { satisfied: false, redirect: fallbackRedirect !== null && fallbackRedirect !== void 0 ? fallbackRedirect : "/signin" };
|
|
114
|
+
}
|
|
115
|
+
const userRoles = Array.isArray(user.roles) ? user.roles : [];
|
|
116
|
+
const userPermissions = Array.isArray(user.permissions)
|
|
117
|
+
? user.permissions
|
|
118
|
+
: [];
|
|
119
|
+
// 1. Core Role Check (At least one role must match)
|
|
120
|
+
if (requiredRoles && requiredRoles.length > 0) {
|
|
121
|
+
const hasRole = requiredRoles.some((role) => userRoles.includes(role));
|
|
122
|
+
if (!hasRole) {
|
|
123
|
+
console.warn(`User lacks required roles: ${requiredRoles.join(", ")}`);
|
|
124
|
+
return {
|
|
125
|
+
satisfied: false,
|
|
126
|
+
redirect: fallbackRedirect,
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
// 2. Core Permission Check (ALL permissions must match)
|
|
131
|
+
if (requiredPermissions && requiredPermissions.length > 0) {
|
|
132
|
+
const hasAllPermissions = requiredPermissions.every((perm) => userPermissions.includes(perm));
|
|
133
|
+
if (!hasAllPermissions) {
|
|
134
|
+
console.warn(`User lacks required permissions: ${requiredPermissions.join(", ")}`);
|
|
135
|
+
return {
|
|
136
|
+
satisfied: false,
|
|
137
|
+
redirect: fallbackRedirect,
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
// 3. Modular Requirements Check
|
|
142
|
+
if (securityRequirements) {
|
|
143
|
+
for (const requirement of securityRequirements) {
|
|
144
|
+
try {
|
|
145
|
+
const result = await requirement(session, user);
|
|
146
|
+
if (result && !result.satisfied) {
|
|
147
|
+
return {
|
|
148
|
+
...result,
|
|
149
|
+
redirect: (_a = result.redirect) !== null && _a !== void 0 ? _a : fallbackRedirect,
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
catch (error) {
|
|
154
|
+
console.error("[Auth:Security] Requirement failed:", error);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
return { satisfied: true };
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Sign In Logic
|
|
162
|
+
*/
|
|
163
|
+
export async function signIn(data) {
|
|
164
|
+
const { email, password } = await loginSchema.parseAsync(data);
|
|
165
|
+
const user = await getUserFromEmail(email);
|
|
166
|
+
if (!user) {
|
|
167
|
+
return { status: "ERROR", message: "Invalid email or password" };
|
|
168
|
+
}
|
|
169
|
+
const passwordHash = await getUserPasswordHash(user.id);
|
|
170
|
+
if (!passwordHash || !(await verifyPasswordHash(passwordHash, password))) {
|
|
171
|
+
return { status: "ERROR", message: "Invalid email or password" };
|
|
172
|
+
}
|
|
173
|
+
// Interception Layer
|
|
174
|
+
for (const validator of authValidators) {
|
|
175
|
+
const interception = await validator(user.id);
|
|
176
|
+
if (interception)
|
|
177
|
+
return interception;
|
|
178
|
+
}
|
|
179
|
+
const sessionFlags = {};
|
|
180
|
+
const sessionToken = await generateSessionToken();
|
|
181
|
+
const session = await createSession(sessionToken, user.id, sessionFlags);
|
|
182
|
+
await setSessionTokenCookie(sessionToken, session.expiresAt);
|
|
183
|
+
const fullUser = await performFullUserAugmentation(user);
|
|
184
|
+
await eventBus.publish("auth:session-created", { session, user: fullUser });
|
|
185
|
+
return {
|
|
186
|
+
status: "SUCCESS",
|
|
187
|
+
session: { ...session },
|
|
188
|
+
user: { ...fullUser },
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Sign Up Logic
|
|
193
|
+
*/
|
|
194
|
+
export async function signUp(data) {
|
|
195
|
+
const { email, username, password } = registerSchema.parse(data);
|
|
196
|
+
if (!(await verifyUsernameInput(username))) {
|
|
197
|
+
throw new Error("Invalid username");
|
|
198
|
+
}
|
|
199
|
+
if (!(await verifyPasswordStrength(password))) {
|
|
200
|
+
throw new Error("Weak password");
|
|
201
|
+
}
|
|
202
|
+
const user = await createUser(email, username, password);
|
|
203
|
+
const verificationRequest = await createEmailVerificationRequest(user.id, user.email);
|
|
204
|
+
await sendVerificationEmail(verificationRequest.email, verificationRequest.code);
|
|
205
|
+
await setEmailVerificationRequestCookie(verificationRequest);
|
|
206
|
+
const sessionFlags = {};
|
|
207
|
+
const sessionToken = await generateSessionToken();
|
|
208
|
+
const session = await createSession(sessionToken, user.id, sessionFlags);
|
|
209
|
+
await setSessionTokenCookie(sessionToken, session.expiresAt);
|
|
210
|
+
const fullUser = await performFullUserAugmentation(user);
|
|
211
|
+
await eventBus.publish("auth:session-created", { session, user: fullUser });
|
|
212
|
+
return {
|
|
213
|
+
session: { ...session },
|
|
214
|
+
user: { ...fullUser },
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Finalizes login after a challenge
|
|
219
|
+
*/
|
|
220
|
+
export async function finalizeLogin(userId, flags) {
|
|
221
|
+
const sessionToken = await generateSessionToken();
|
|
222
|
+
const session = await createSession(sessionToken, userId, flags);
|
|
223
|
+
await setSessionTokenCookie(sessionToken, session.expiresAt);
|
|
224
|
+
const user = await getUserById(userId);
|
|
225
|
+
if (user) {
|
|
226
|
+
await eventBus.publish("auth:session-created", { session, user });
|
|
227
|
+
}
|
|
228
|
+
return {
|
|
229
|
+
session: session ? { ...session } : null,
|
|
230
|
+
user: user ? { ...user } : null,
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Sign Out
|
|
235
|
+
*/
|
|
236
|
+
export async function signOut() {
|
|
237
|
+
const { session, user } = await getCurrentSession();
|
|
238
|
+
if (session) {
|
|
239
|
+
if (user) {
|
|
240
|
+
await eventBus.publish("auth:signed-out", { userId: user.id });
|
|
241
|
+
}
|
|
242
|
+
await invalidateSession(session.id);
|
|
243
|
+
await deleteSessionTokenCookie();
|
|
244
|
+
}
|
|
245
|
+
}
|