@arch-cadre/core 0.0.6
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/_virtual/_rolldown/runtime.cjs +29 -0
- package/dist/_virtual/_rolldown/runtime.mjs +18 -0
- package/dist/core/auth/augment.cjs +71 -0
- package/dist/core/auth/augment.d.cts +20 -0
- package/dist/core/auth/augment.d.cts.map +1 -0
- package/dist/core/auth/augment.d.mts +20 -0
- package/dist/core/auth/augment.d.mts.map +1 -0
- package/dist/core/auth/augment.mjs +66 -0
- package/dist/core/auth/augment.mjs.map +1 -0
- package/dist/core/auth/email-verification.cjs +99 -0
- package/dist/core/auth/email-verification.d.cts +62 -0
- package/dist/core/auth/email-verification.d.cts.map +1 -0
- package/dist/core/auth/email-verification.d.mts +62 -0
- package/dist/core/auth/email-verification.d.mts.map +1 -0
- package/dist/core/auth/email-verification.mjs +92 -0
- package/dist/core/auth/email-verification.mjs.map +1 -0
- package/dist/core/auth/logic.cjs +224 -0
- package/dist/core/auth/logic.d.cts +110 -0
- package/dist/core/auth/logic.d.cts.map +1 -0
- package/dist/core/auth/logic.d.mts +110 -0
- package/dist/core/auth/logic.d.mts.map +1 -0
- package/dist/core/auth/logic.mjs +213 -0
- package/dist/core/auth/logic.mjs.map +1 -0
- package/dist/core/auth/password-reset.cjs +118 -0
- package/dist/core/auth/password-reset.d.cts +39 -0
- package/dist/core/auth/password-reset.d.cts.map +1 -0
- package/dist/core/auth/password-reset.d.mts +39 -0
- package/dist/core/auth/password-reset.d.mts.map +1 -0
- package/dist/core/auth/password-reset.mjs +111 -0
- package/dist/core/auth/password-reset.mjs.map +1 -0
- package/dist/core/auth/rbac.cjs +118 -0
- package/dist/core/auth/rbac.d.cts +61 -0
- package/dist/core/auth/rbac.d.cts.map +1 -0
- package/dist/core/auth/rbac.d.mts +61 -0
- package/dist/core/auth/rbac.d.mts.map +1 -0
- package/dist/core/auth/rbac.mjs +104 -0
- package/dist/core/auth/rbac.mjs.map +1 -0
- package/dist/core/auth/session.cjs +161 -0
- package/dist/core/auth/session.d.cts +54 -0
- package/dist/core/auth/session.d.cts.map +1 -0
- package/dist/core/auth/session.d.mts +54 -0
- package/dist/core/auth/session.d.mts.map +1 -0
- package/dist/core/auth/session.mjs +150 -0
- package/dist/core/auth/session.mjs.map +1 -0
- package/dist/core/auth/types.d.cts +55 -0
- package/dist/core/auth/types.d.cts.map +1 -0
- package/dist/core/auth/types.d.mts +55 -0
- package/dist/core/auth/types.d.mts.map +1 -0
- package/dist/core/auth/utils/encode.cjs +27 -0
- package/dist/core/auth/utils/encode.d.cts +15 -0
- package/dist/core/auth/utils/encode.d.cts.map +1 -0
- package/dist/core/auth/utils/encode.d.mts +15 -0
- package/dist/core/auth/utils/encode.d.mts.map +1 -0
- package/dist/core/auth/utils/encode.mjs +26 -0
- package/dist/core/auth/utils/encode.mjs.map +1 -0
- package/dist/core/auth/utils/encryption.cjs +67 -0
- package/dist/core/auth/utils/encryption.d.cts +28 -0
- package/dist/core/auth/utils/encryption.d.cts.map +1 -0
- package/dist/core/auth/utils/encryption.d.mts +28 -0
- package/dist/core/auth/utils/encryption.d.mts.map +1 -0
- package/dist/core/auth/utils/encryption.mjs +64 -0
- package/dist/core/auth/utils/encryption.mjs.map +1 -0
- package/dist/core/auth/validation.cjs +39 -0
- package/dist/core/auth/validation.d.cts +48 -0
- package/dist/core/auth/validation.d.cts.map +1 -0
- package/dist/core/auth/validation.d.mts +48 -0
- package/dist/core/auth/validation.d.mts.map +1 -0
- package/dist/core/auth/validation.mjs +31 -0
- package/dist/core/auth/validation.mjs.map +1 -0
- package/dist/core/bootstrap.cjs +32 -0
- package/dist/core/bootstrap.d.cts +5 -0
- package/dist/core/bootstrap.d.cts.map +1 -0
- package/dist/core/bootstrap.d.mts +5 -0
- package/dist/core/bootstrap.d.mts.map +1 -0
- package/dist/core/bootstrap.mjs +33 -0
- package/dist/core/bootstrap.mjs.map +1 -0
- package/dist/core/config.cjs +6 -0
- package/dist/core/config.d.cts +11 -0
- package/dist/core/config.d.cts.map +1 -0
- package/dist/core/config.d.mts +11 -0
- package/dist/core/config.d.mts.map +1 -0
- package/dist/core/config.mjs +6 -0
- package/dist/core/config.mjs.map +1 -0
- package/dist/core/config.server.cjs +60 -0
- package/dist/core/config.server.d.cts +16 -0
- package/dist/core/config.server.d.cts.map +1 -0
- package/dist/core/config.server.d.mts +16 -0
- package/dist/core/config.server.d.mts.map +1 -0
- package/dist/core/config.server.mjs +57 -0
- package/dist/core/config.server.mjs.map +1 -0
- package/dist/core/event-bus.cjs +48 -0
- package/dist/core/event-bus.d.cts +17 -0
- package/dist/core/event-bus.d.cts.map +1 -0
- package/dist/core/event-bus.d.mts +17 -0
- package/dist/core/event-bus.d.mts.map +1 -0
- package/dist/core/event-bus.mjs +48 -0
- package/dist/core/event-bus.mjs.map +1 -0
- package/dist/core/filesystem/service.cjs +43 -0
- package/dist/core/filesystem/service.d.cts +19 -0
- package/dist/core/filesystem/service.d.cts.map +1 -0
- package/dist/core/filesystem/service.d.mts +19 -0
- package/dist/core/filesystem/service.d.mts.map +1 -0
- package/dist/core/filesystem/service.mjs +43 -0
- package/dist/core/filesystem/service.mjs.map +1 -0
- package/dist/core/filesystem/types.d.cts +22 -0
- package/dist/core/filesystem/types.d.cts.map +1 -0
- package/dist/core/filesystem/types.d.mts +22 -0
- package/dist/core/filesystem/types.d.mts.map +1 -0
- package/dist/core/notifications/actions.cjs +36 -0
- package/dist/core/notifications/actions.d.cts +58 -0
- package/dist/core/notifications/actions.d.cts.map +1 -0
- package/dist/core/notifications/actions.d.mts +58 -0
- package/dist/core/notifications/actions.d.mts.map +1 -0
- package/dist/core/notifications/actions.mjs +33 -0
- package/dist/core/notifications/actions.mjs.map +1 -0
- package/dist/core/notifications/index.cjs +2 -0
- package/dist/core/notifications/index.mjs +4 -0
- package/dist/core/notifications/service.cjs +30 -0
- package/dist/core/notifications/service.d.cts +9 -0
- package/dist/core/notifications/service.d.cts.map +1 -0
- package/dist/core/notifications/service.d.mts +9 -0
- package/dist/core/notifications/service.d.mts.map +1 -0
- package/dist/core/notifications/service.mjs +31 -0
- package/dist/core/notifications/service.mjs.map +1 -0
- package/dist/core/notifications/types.d.cts +21 -0
- package/dist/core/notifications/types.d.cts.map +1 -0
- package/dist/core/notifications/types.d.mts +21 -0
- package/dist/core/notifications/types.d.mts.map +1 -0
- package/dist/core/setup.cjs +25 -0
- package/dist/core/setup.d.cts +9 -0
- package/dist/core/setup.d.cts.map +1 -0
- package/dist/core/setup.d.mts +9 -0
- package/dist/core/setup.d.mts.map +1 -0
- package/dist/core/setup.mjs +25 -0
- package/dist/core/setup.mjs.map +1 -0
- package/dist/core/types.d.cts +13 -0
- package/dist/core/types.d.cts.map +1 -0
- package/dist/core/types.d.mts +13 -0
- package/dist/core/types.d.mts.map +1 -0
- package/dist/index.cjs +30 -0
- package/dist/index.d.cts +8 -0
- package/dist/index.d.mts +8 -0
- package/dist/index.mjs +6 -0
- package/dist/server/auth/email.cjs +24 -0
- package/dist/server/auth/email.d.cts +13 -0
- package/dist/server/auth/email.d.cts.map +1 -0
- package/dist/server/auth/email.d.mts +13 -0
- package/dist/server/auth/email.d.mts.map +1 -0
- package/dist/server/auth/email.mjs +23 -0
- package/dist/server/auth/email.mjs.map +1 -0
- package/dist/server/auth/password.cjs +37 -0
- package/dist/server/auth/password.d.cts +23 -0
- package/dist/server/auth/password.d.cts.map +1 -0
- package/dist/server/auth/password.d.mts +23 -0
- package/dist/server/auth/password.d.mts.map +1 -0
- package/dist/server/auth/password.mjs +34 -0
- package/dist/server/auth/password.mjs.map +1 -0
- package/dist/server/auth/user.cjs +165 -0
- package/dist/server/auth/user.d.cts +58 -0
- package/dist/server/auth/user.d.cts.map +1 -0
- package/dist/server/auth/user.d.mts +58 -0
- package/dist/server/auth/user.d.mts.map +1 -0
- package/dist/server/auth/user.mjs +153 -0
- package/dist/server/auth/user.mjs.map +1 -0
- package/dist/server/database/inject.cjs +24 -0
- package/dist/server/database/inject.d.cts +15 -0
- package/dist/server/database/inject.d.cts.map +1 -0
- package/dist/server/database/inject.d.mts +15 -0
- package/dist/server/database/inject.d.mts.map +1 -0
- package/dist/server/database/inject.mjs +23 -0
- package/dist/server/database/inject.mjs.map +1 -0
- package/dist/server/database/schema.cjs +163 -0
- package/dist/server/database/schema.d.cts +2962 -0
- package/dist/server/database/schema.d.cts.map +1 -0
- package/dist/server/database/schema.d.mts +2962 -0
- package/dist/server/database/schema.d.mts.map +1 -0
- package/dist/server/database/schema.mjs +151 -0
- package/dist/server/database/schema.mjs.map +1 -0
- package/dist/server/emails/index.cjs +32 -0
- package/dist/server/emails/index.d.cts +26 -0
- package/dist/server/emails/index.d.cts.map +1 -0
- package/dist/server/emails/index.d.mts +26 -0
- package/dist/server/emails/index.d.mts.map +1 -0
- package/dist/server/emails/index.mjs +29 -0
- package/dist/server/emails/index.mjs.map +1 -0
- package/dist/server.cjs +145 -0
- package/dist/server.d.cts +26 -0
- package/dist/server.d.mts +26 -0
- package/dist/server.mjs +23 -0
- package/package.json +60 -0
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
"use server";
|
|
2
|
+
|
|
3
|
+
const require_runtime = require('../../_virtual/_rolldown/runtime.cjs');
|
|
4
|
+
const require_validation = require('./validation.cjs');
|
|
5
|
+
const require_event_bus = require('../event-bus.cjs');
|
|
6
|
+
const require_inject = require('../../server/database/inject.cjs');
|
|
7
|
+
const require_schema = require('../../server/database/schema.cjs');
|
|
8
|
+
const require_password = require('../../server/auth/password.cjs');
|
|
9
|
+
const require_user = require('../../server/auth/user.cjs');
|
|
10
|
+
const require_augment = require('./augment.cjs');
|
|
11
|
+
const require_email_verification = require('./email-verification.cjs');
|
|
12
|
+
const require_session = require('./session.cjs');
|
|
13
|
+
let drizzle_orm = require("drizzle-orm");
|
|
14
|
+
|
|
15
|
+
//#region src/core/auth/logic.ts
|
|
16
|
+
/**
|
|
17
|
+
* Podstawowy moduł rozszerzający tożsamość dla ról i uprawnień
|
|
18
|
+
*/
|
|
19
|
+
async function coreRbacAugmenter(user) {
|
|
20
|
+
try {
|
|
21
|
+
const roles = (await require_inject.db.select({ name: require_schema.rolesTable.name }).from(require_schema.usersToRolesTable).innerJoin(require_schema.rolesTable, (0, drizzle_orm.eq)(require_schema.usersToRolesTable.roleId, require_schema.rolesTable.id)).where((0, drizzle_orm.eq)(require_schema.usersToRolesTable.userId, user.id))).map((r) => r.name);
|
|
22
|
+
const directPerms = (await require_inject.db.select({ name: require_schema.permissionsTable.name }).from(require_schema.usersToPermissionsTable).innerJoin(require_schema.permissionsTable, (0, drizzle_orm.eq)(require_schema.usersToPermissionsTable.permissionId, require_schema.permissionsTable.id)).where((0, drizzle_orm.eq)(require_schema.usersToPermissionsTable.userId, user.id))).map((p) => p.name);
|
|
23
|
+
let rolePerms = [];
|
|
24
|
+
if (roles.length > 0) {
|
|
25
|
+
const roleIds = (await require_inject.db.select({ id: require_schema.rolesTable.id }).from(require_schema.rolesTable).where((0, drizzle_orm.inArray)(require_schema.rolesTable.name, roles))).map((r) => r.id);
|
|
26
|
+
if (roleIds.length > 0) rolePerms = (await require_inject.db.select({ name: require_schema.permissionsTable.name }).from(require_schema.rolesToPermissionsTable).innerJoin(require_schema.permissionsTable, (0, drizzle_orm.eq)(require_schema.rolesToPermissionsTable.permissionId, require_schema.permissionsTable.id)).where((0, drizzle_orm.inArray)(require_schema.rolesToPermissionsTable.roleId, roleIds))).map((p) => p.name);
|
|
27
|
+
}
|
|
28
|
+
return {
|
|
29
|
+
roles,
|
|
30
|
+
permissions: Array.from(new Set([...directPerms, ...rolePerms]))
|
|
31
|
+
};
|
|
32
|
+
} catch (error) {
|
|
33
|
+
console.error("[Auth:RBAC] Failed to augment user:", error);
|
|
34
|
+
return {
|
|
35
|
+
roles: [],
|
|
36
|
+
permissions: []
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
const globalForAuth = globalThis;
|
|
41
|
+
const authValidators = globalForAuth.__WINKLY_AUTH_VALIDATORS__ ?? /* @__PURE__ */ new Set();
|
|
42
|
+
const securityRequirements = globalForAuth.__WINKLY_SECURITY_REQUIREMENTS__ ?? /* @__PURE__ */ new Set();
|
|
43
|
+
const passwordResetValidators = globalForAuth.__WINKLY_PASSWORD_RESET_VALIDATORS__ ?? /* @__PURE__ */ new Set();
|
|
44
|
+
const emailVerificationValidators = globalForAuth.__WINKLY_EMAIL_VERIFICATION_VALIDATORS__ ?? /* @__PURE__ */ new Set();
|
|
45
|
+
globalForAuth.__WINKLY_AUTH_VALIDATORS__ = authValidators;
|
|
46
|
+
globalForAuth.__WINKLY_SECURITY_REQUIREMENTS__ = securityRequirements;
|
|
47
|
+
globalForAuth.__WINKLY_PASSWORD_RESET_VALIDATORS__ = passwordResetValidators;
|
|
48
|
+
globalForAuth.__WINKLY_EMAIL_VERIFICATION_VALIDATORS__ = emailVerificationValidators;
|
|
49
|
+
async function registerAuthValidator(validator) {
|
|
50
|
+
authValidators.add(validator);
|
|
51
|
+
}
|
|
52
|
+
async function registerPasswordResetValidator(validator) {
|
|
53
|
+
passwordResetValidators.add(validator);
|
|
54
|
+
}
|
|
55
|
+
async function registerEmailVerificationValidator(validator) {
|
|
56
|
+
emailVerificationValidators.add(validator);
|
|
57
|
+
}
|
|
58
|
+
async function registerSecurityRequirement(requirement) {
|
|
59
|
+
securityRequirements.add(requirement);
|
|
60
|
+
}
|
|
61
|
+
async function runPasswordResetValidators(userId) {
|
|
62
|
+
for (const validator of passwordResetValidators) {
|
|
63
|
+
const interception = await validator(userId);
|
|
64
|
+
if (interception) return interception;
|
|
65
|
+
}
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
async function runEmailVerificationValidators(userId) {
|
|
69
|
+
for (const validator of emailVerificationValidators) {
|
|
70
|
+
const interception = await validator(userId);
|
|
71
|
+
if (interception) return interception;
|
|
72
|
+
}
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Augments a base user with data from all registered modules.
|
|
77
|
+
* This is now just a wrapper that includes core RBAC data.
|
|
78
|
+
*/
|
|
79
|
+
async function performFullUserAugmentation(user) {
|
|
80
|
+
return await require_augment.augmentUser(user, await coreRbacAugmenter(user));
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Checks if the current session satisfies all registered security requirements.
|
|
84
|
+
*/
|
|
85
|
+
async function checkSecurity(session, user, requiredRoles, requiredPermissions, fallbackRedirect) {
|
|
86
|
+
if (!user) {
|
|
87
|
+
console.warn("User is required for security check");
|
|
88
|
+
return {
|
|
89
|
+
satisfied: false,
|
|
90
|
+
redirect: fallbackRedirect ?? "/signin"
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
const userRoles = Array.isArray(user.roles) ? user.roles : [];
|
|
94
|
+
const userPermissions = Array.isArray(user.permissions) ? user.permissions : [];
|
|
95
|
+
if (requiredRoles && requiredRoles.length > 0) {
|
|
96
|
+
if (!requiredRoles.some((role) => userRoles.includes(role))) {
|
|
97
|
+
console.warn(`User lacks required roles: ${requiredRoles.join(", ")}`);
|
|
98
|
+
return {
|
|
99
|
+
satisfied: false,
|
|
100
|
+
redirect: fallbackRedirect
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
if (requiredPermissions && requiredPermissions.length > 0) {
|
|
105
|
+
if (!requiredPermissions.every((perm) => userPermissions.includes(perm))) {
|
|
106
|
+
console.warn(`User lacks required permissions: ${requiredPermissions.join(", ")}`);
|
|
107
|
+
return {
|
|
108
|
+
satisfied: false,
|
|
109
|
+
redirect: fallbackRedirect
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
if (securityRequirements) for (const requirement of securityRequirements) try {
|
|
114
|
+
const result = await requirement(session, user);
|
|
115
|
+
if (result && !result.satisfied) return {
|
|
116
|
+
...result,
|
|
117
|
+
redirect: result.redirect ?? fallbackRedirect
|
|
118
|
+
};
|
|
119
|
+
} catch (error) {
|
|
120
|
+
console.error("[Auth:Security] Requirement failed:", error);
|
|
121
|
+
}
|
|
122
|
+
return { satisfied: true };
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Sign In Logic
|
|
126
|
+
*/
|
|
127
|
+
async function signIn(data) {
|
|
128
|
+
const { email, password } = await require_validation.loginSchema.parseAsync(data);
|
|
129
|
+
const user = await require_user.getUserFromEmail(email);
|
|
130
|
+
if (!user) return {
|
|
131
|
+
status: "ERROR",
|
|
132
|
+
message: "Invalid email or password"
|
|
133
|
+
};
|
|
134
|
+
const passwordHash = await require_user.getUserPasswordHash(user.id);
|
|
135
|
+
if (!passwordHash || !await require_password.verifyPasswordHash(passwordHash, password)) return {
|
|
136
|
+
status: "ERROR",
|
|
137
|
+
message: "Invalid email or password"
|
|
138
|
+
};
|
|
139
|
+
for (const validator of authValidators) {
|
|
140
|
+
const interception = await validator(user.id);
|
|
141
|
+
if (interception) return interception;
|
|
142
|
+
}
|
|
143
|
+
const sessionFlags = {};
|
|
144
|
+
const sessionToken = await require_session.generateSessionToken();
|
|
145
|
+
const session = await require_session.createSession(sessionToken, user.id, sessionFlags);
|
|
146
|
+
await require_session.setSessionTokenCookie(sessionToken, session.expiresAt);
|
|
147
|
+
const fullUser = await performFullUserAugmentation(user);
|
|
148
|
+
await require_event_bus.eventBus.publish("auth:session-created", {
|
|
149
|
+
session,
|
|
150
|
+
user: fullUser
|
|
151
|
+
});
|
|
152
|
+
return {
|
|
153
|
+
status: "SUCCESS",
|
|
154
|
+
session: { ...session },
|
|
155
|
+
user: { ...fullUser }
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Sign Up Logic
|
|
160
|
+
*/
|
|
161
|
+
async function signUp(data) {
|
|
162
|
+
const { email, username, password } = require_validation.registerSchema.parse(data);
|
|
163
|
+
if (!await require_user.verifyUsernameInput(username)) throw new Error("Invalid username");
|
|
164
|
+
if (!await require_password.verifyPasswordStrength(password)) throw new Error("Weak password");
|
|
165
|
+
const user = await require_user.createUser(email, username, password);
|
|
166
|
+
const verificationRequest = await require_email_verification.createEmailVerificationRequest(user.id, user.email);
|
|
167
|
+
await require_email_verification.sendVerificationEmail(verificationRequest.email, verificationRequest.code);
|
|
168
|
+
await require_email_verification.setEmailVerificationRequestCookie(verificationRequest);
|
|
169
|
+
const sessionFlags = {};
|
|
170
|
+
const sessionToken = await require_session.generateSessionToken();
|
|
171
|
+
const session = await require_session.createSession(sessionToken, user.id, sessionFlags);
|
|
172
|
+
await require_session.setSessionTokenCookie(sessionToken, session.expiresAt);
|
|
173
|
+
const fullUser = await performFullUserAugmentation(user);
|
|
174
|
+
await require_event_bus.eventBus.publish("auth:session-created", {
|
|
175
|
+
session,
|
|
176
|
+
user: fullUser
|
|
177
|
+
});
|
|
178
|
+
return {
|
|
179
|
+
session: { ...session },
|
|
180
|
+
user: { ...fullUser }
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Finalizes login after a challenge
|
|
185
|
+
*/
|
|
186
|
+
async function finalizeLogin(userId, flags) {
|
|
187
|
+
const sessionToken = await require_session.generateSessionToken();
|
|
188
|
+
const session = await require_session.createSession(sessionToken, userId, flags);
|
|
189
|
+
await require_session.setSessionTokenCookie(sessionToken, session.expiresAt);
|
|
190
|
+
const user = await require_user.getUserById(userId);
|
|
191
|
+
if (user) await require_event_bus.eventBus.publish("auth:session-created", {
|
|
192
|
+
session,
|
|
193
|
+
user
|
|
194
|
+
});
|
|
195
|
+
return {
|
|
196
|
+
session: session ? { ...session } : null,
|
|
197
|
+
user: user ? { ...user } : null
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Sign Out
|
|
202
|
+
*/
|
|
203
|
+
async function signOut() {
|
|
204
|
+
const { session, user } = await require_session.getCurrentSession();
|
|
205
|
+
if (session) {
|
|
206
|
+
if (user) await require_event_bus.eventBus.publish("auth:signed-out", { userId: user.id });
|
|
207
|
+
await require_session.invalidateSession(session.id);
|
|
208
|
+
await require_session.deleteSessionTokenCookie();
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
//#endregion
|
|
213
|
+
exports.checkSecurity = checkSecurity;
|
|
214
|
+
exports.finalizeLogin = finalizeLogin;
|
|
215
|
+
exports.performFullUserAugmentation = performFullUserAugmentation;
|
|
216
|
+
exports.registerAuthValidator = registerAuthValidator;
|
|
217
|
+
exports.registerEmailVerificationValidator = registerEmailVerificationValidator;
|
|
218
|
+
exports.registerPasswordResetValidator = registerPasswordResetValidator;
|
|
219
|
+
exports.registerSecurityRequirement = registerSecurityRequirement;
|
|
220
|
+
exports.runEmailVerificationValidators = runEmailVerificationValidators;
|
|
221
|
+
exports.runPasswordResetValidators = runPasswordResetValidators;
|
|
222
|
+
exports.signIn = signIn;
|
|
223
|
+
exports.signOut = signOut;
|
|
224
|
+
exports.signUp = signUp;
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { UserPermission, UserRole } from "../types.cjs";
|
|
2
|
+
import { AuthResponse, FullUser, Session, SessionFlags, User } from "./types.cjs";
|
|
3
|
+
import { LoginInput, RegisterInput } from "./validation.cjs";
|
|
4
|
+
import { augmentSession, augmentUser, registerIdentityAugmenter, registerPasswordResetSessionAugmenter, registerSessionAugmenter } from "./augment.cjs";
|
|
5
|
+
|
|
6
|
+
//#region src/core/auth/logic.d.ts
|
|
7
|
+
/**
|
|
8
|
+
* Registry for login validators (e.g. 2FA module)
|
|
9
|
+
*/
|
|
10
|
+
type AuthValidator = (userId: string) => Promise<AuthResponse | null>;
|
|
11
|
+
/**
|
|
12
|
+
* Registry for Security Requirements (e.g. checking if 2FA is needed for a session)
|
|
13
|
+
*/
|
|
14
|
+
type SecurityRequirement = (session: Session, user: FullUser) => Promise<{
|
|
15
|
+
satisfied: boolean;
|
|
16
|
+
redirect?: string;
|
|
17
|
+
} | null>;
|
|
18
|
+
/**
|
|
19
|
+
* Registry for password reset validators (e.g. 2FA module requiring check during reset)
|
|
20
|
+
*/
|
|
21
|
+
type PasswordResetValidator = (userId: string) => Promise<AuthResponse | null>;
|
|
22
|
+
/**
|
|
23
|
+
* Registry for email verification validators
|
|
24
|
+
*/
|
|
25
|
+
type EmailVerificationValidator = (userId: string) => Promise<AuthResponse | null>;
|
|
26
|
+
declare function registerAuthValidator(validator: AuthValidator): Promise<void>;
|
|
27
|
+
declare function registerPasswordResetValidator(validator: PasswordResetValidator): Promise<void>;
|
|
28
|
+
declare function registerEmailVerificationValidator(validator: EmailVerificationValidator): Promise<void>;
|
|
29
|
+
declare function registerSecurityRequirement(requirement: SecurityRequirement): Promise<void>;
|
|
30
|
+
declare function runPasswordResetValidators(userId: string): Promise<AuthResponse | null>;
|
|
31
|
+
declare function runEmailVerificationValidators(userId: string): Promise<AuthResponse | null>;
|
|
32
|
+
/**
|
|
33
|
+
* Augments a base user with data from all registered modules.
|
|
34
|
+
* This is now just a wrapper that includes core RBAC data.
|
|
35
|
+
*/
|
|
36
|
+
declare function performFullUserAugmentation(user: User): Promise<FullUser>;
|
|
37
|
+
/**
|
|
38
|
+
* Checks if the current session satisfies all registered security requirements.
|
|
39
|
+
*/
|
|
40
|
+
declare function checkSecurity(session: Session, user: FullUser, requiredRoles?: UserRole[], requiredPermissions?: UserPermission[], fallbackRedirect?: string): Promise<{
|
|
41
|
+
satisfied: boolean;
|
|
42
|
+
redirect: string | undefined;
|
|
43
|
+
} | {
|
|
44
|
+
satisfied: boolean;
|
|
45
|
+
redirect?: undefined;
|
|
46
|
+
}>;
|
|
47
|
+
/**
|
|
48
|
+
* Sign In Logic
|
|
49
|
+
*/
|
|
50
|
+
declare function signIn(data: LoginInput): Promise<AuthResponse>;
|
|
51
|
+
/**
|
|
52
|
+
* Sign Up Logic
|
|
53
|
+
*/
|
|
54
|
+
declare function signUp(data: RegisterInput): Promise<{
|
|
55
|
+
session: {
|
|
56
|
+
[x: string]: any;
|
|
57
|
+
id: string;
|
|
58
|
+
createdAt: Date;
|
|
59
|
+
updatedAt: Date | null;
|
|
60
|
+
userId: string;
|
|
61
|
+
active_organization_id: string | null;
|
|
62
|
+
expiresAt: Date;
|
|
63
|
+
};
|
|
64
|
+
user: {
|
|
65
|
+
[x: string]: any;
|
|
66
|
+
id: string;
|
|
67
|
+
email: string;
|
|
68
|
+
name: string;
|
|
69
|
+
password: string | null;
|
|
70
|
+
image: string | null;
|
|
71
|
+
recovery_code: Buffer<ArrayBufferLike>;
|
|
72
|
+
emailVerifiedAt: Date | null;
|
|
73
|
+
createdAt: Date;
|
|
74
|
+
updatedAt: Date | null;
|
|
75
|
+
roles: UserRole[];
|
|
76
|
+
permissions: UserPermission[];
|
|
77
|
+
};
|
|
78
|
+
}>;
|
|
79
|
+
/**
|
|
80
|
+
* Finalizes login after a challenge
|
|
81
|
+
*/
|
|
82
|
+
declare function finalizeLogin(userId: string, flags: SessionFlags): Promise<{
|
|
83
|
+
session: {
|
|
84
|
+
[x: string]: any;
|
|
85
|
+
id: string;
|
|
86
|
+
createdAt: Date;
|
|
87
|
+
updatedAt: Date | null;
|
|
88
|
+
userId: string;
|
|
89
|
+
active_organization_id: string | null;
|
|
90
|
+
expiresAt: Date;
|
|
91
|
+
} | null;
|
|
92
|
+
user: {
|
|
93
|
+
id: string;
|
|
94
|
+
email: string;
|
|
95
|
+
name: string;
|
|
96
|
+
password: string | null;
|
|
97
|
+
image: string | null;
|
|
98
|
+
recovery_code: Buffer<ArrayBufferLike>;
|
|
99
|
+
emailVerifiedAt: Date | null;
|
|
100
|
+
createdAt: Date;
|
|
101
|
+
updatedAt: Date | null;
|
|
102
|
+
} | null;
|
|
103
|
+
}>;
|
|
104
|
+
/**
|
|
105
|
+
* Sign Out
|
|
106
|
+
*/
|
|
107
|
+
declare function signOut(): Promise<void>;
|
|
108
|
+
//#endregion
|
|
109
|
+
export { checkSecurity, finalizeLogin, performFullUserAugmentation, registerAuthValidator, registerEmailVerificationValidator, registerPasswordResetValidator, registerSecurityRequirement, runEmailVerificationValidators, runPasswordResetValidators, signIn, signOut, signUp };
|
|
110
|
+
//# sourceMappingURL=logic.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logic.d.cts","names":[],"sources":["../../../src/core/auth/logic.ts"],"mappings":";;;;;;;;;KAyHK,aAAA,IAAiB,MAAA,aAAmB,OAAA,CAAQ,YAAA;;;;KAK5C,mBAAA,IACH,OAAA,EAAS,OAAA,EACT,IAAA,EAAM,QAAA,KACH,OAAA;EAAU,SAAA;EAAoB,QAAA;AAAA;;AAR0B;;KAaxD,sBAAA,IAA0B,MAAA,aAAmB,OAAA,CAAQ,YAAA;;;;KAKrD,0BAAA,IACH,MAAA,aACG,OAAA,CAAQ,YAAA;AAAA,iBA6BS,qBAAA,CAAsB,SAAA,EAAW,aAAA,GAAa,OAAA;AAAA,iBAI9C,8BAAA,CACpB,SAAA,EAAW,sBAAA,GAAsB,OAAA;AAAA,iBAKb,kCAAA,CACpB,SAAA,EAAW,0BAAA,GAA0B,OAAA;AAAA,iBAajB,2BAAA,CACpB,WAAA,EAAa,mBAAA,GAAmB,OAAA;AAAA,iBAKZ,0BAAA,CACpB,MAAA,WACC,OAAA,CAAQ,YAAA;AAAA,iBAQW,8BAAA,CACpB,MAAA,WACC,OAAA,CAAQ,YAAA;;;;AAnFgC;iBA+FrB,2BAAA,CACpB,IAAA,EAAM,IAAA,GACL,OAAA,CAAQ,QAAA;;;;iBAQW,aAAA,CACpB,OAAA,EAAS,OAAA,EACT,IAAA,EAAM,QAAA,EACN,aAAA,GAAgB,QAAA,IAChB,mBAAA,GAAsB,cAAA,IACtB,gBAAA,YAAyB,OAAA;;;;;;;;;;iBA+DL,MAAA,CAAO,IAAA,EAAM,UAAA,GAAa,OAAA,CAAQ,YAAA;;;AApIxD;iBAyKsB,MAAA,CAAO,IAAA,EAAM,aAAA,GAAa,OAAA;;;;;;;;;;;;;;;;;;;;;;;;;;AAjJhD;;iBAyLsB,aAAA,CAAc,MAAA,UAAgB,KAAA,EAAO,YAAA,GAAY,OAAA;;;;;;;;;;;;;;;;;;;;;;;;;iBAoBjD,OAAA,CAAA,GAAO,OAAA"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { UserPermission, UserRole } from "../types.mjs";
|
|
2
|
+
import { AuthResponse, FullUser, Session, SessionFlags, User } from "./types.mjs";
|
|
3
|
+
import { LoginInput, RegisterInput } from "./validation.mjs";
|
|
4
|
+
import { augmentSession, augmentUser, registerIdentityAugmenter, registerPasswordResetSessionAugmenter, registerSessionAugmenter } from "./augment.mjs";
|
|
5
|
+
|
|
6
|
+
//#region src/core/auth/logic.d.ts
|
|
7
|
+
/**
|
|
8
|
+
* Registry for login validators (e.g. 2FA module)
|
|
9
|
+
*/
|
|
10
|
+
type AuthValidator = (userId: string) => Promise<AuthResponse | null>;
|
|
11
|
+
/**
|
|
12
|
+
* Registry for Security Requirements (e.g. checking if 2FA is needed for a session)
|
|
13
|
+
*/
|
|
14
|
+
type SecurityRequirement = (session: Session, user: FullUser) => Promise<{
|
|
15
|
+
satisfied: boolean;
|
|
16
|
+
redirect?: string;
|
|
17
|
+
} | null>;
|
|
18
|
+
/**
|
|
19
|
+
* Registry for password reset validators (e.g. 2FA module requiring check during reset)
|
|
20
|
+
*/
|
|
21
|
+
type PasswordResetValidator = (userId: string) => Promise<AuthResponse | null>;
|
|
22
|
+
/**
|
|
23
|
+
* Registry for email verification validators
|
|
24
|
+
*/
|
|
25
|
+
type EmailVerificationValidator = (userId: string) => Promise<AuthResponse | null>;
|
|
26
|
+
declare function registerAuthValidator(validator: AuthValidator): Promise<void>;
|
|
27
|
+
declare function registerPasswordResetValidator(validator: PasswordResetValidator): Promise<void>;
|
|
28
|
+
declare function registerEmailVerificationValidator(validator: EmailVerificationValidator): Promise<void>;
|
|
29
|
+
declare function registerSecurityRequirement(requirement: SecurityRequirement): Promise<void>;
|
|
30
|
+
declare function runPasswordResetValidators(userId: string): Promise<AuthResponse | null>;
|
|
31
|
+
declare function runEmailVerificationValidators(userId: string): Promise<AuthResponse | null>;
|
|
32
|
+
/**
|
|
33
|
+
* Augments a base user with data from all registered modules.
|
|
34
|
+
* This is now just a wrapper that includes core RBAC data.
|
|
35
|
+
*/
|
|
36
|
+
declare function performFullUserAugmentation(user: User): Promise<FullUser>;
|
|
37
|
+
/**
|
|
38
|
+
* Checks if the current session satisfies all registered security requirements.
|
|
39
|
+
*/
|
|
40
|
+
declare function checkSecurity(session: Session, user: FullUser, requiredRoles?: UserRole[], requiredPermissions?: UserPermission[], fallbackRedirect?: string): Promise<{
|
|
41
|
+
satisfied: boolean;
|
|
42
|
+
redirect: string | undefined;
|
|
43
|
+
} | {
|
|
44
|
+
satisfied: boolean;
|
|
45
|
+
redirect?: undefined;
|
|
46
|
+
}>;
|
|
47
|
+
/**
|
|
48
|
+
* Sign In Logic
|
|
49
|
+
*/
|
|
50
|
+
declare function signIn(data: LoginInput): Promise<AuthResponse>;
|
|
51
|
+
/**
|
|
52
|
+
* Sign Up Logic
|
|
53
|
+
*/
|
|
54
|
+
declare function signUp(data: RegisterInput): Promise<{
|
|
55
|
+
session: {
|
|
56
|
+
[x: string]: any;
|
|
57
|
+
id: string;
|
|
58
|
+
createdAt: Date;
|
|
59
|
+
updatedAt: Date | null;
|
|
60
|
+
userId: string;
|
|
61
|
+
active_organization_id: string | null;
|
|
62
|
+
expiresAt: Date;
|
|
63
|
+
};
|
|
64
|
+
user: {
|
|
65
|
+
[x: string]: any;
|
|
66
|
+
id: string;
|
|
67
|
+
email: string;
|
|
68
|
+
name: string;
|
|
69
|
+
password: string | null;
|
|
70
|
+
image: string | null;
|
|
71
|
+
recovery_code: Buffer<ArrayBufferLike>;
|
|
72
|
+
emailVerifiedAt: Date | null;
|
|
73
|
+
createdAt: Date;
|
|
74
|
+
updatedAt: Date | null;
|
|
75
|
+
roles: UserRole[];
|
|
76
|
+
permissions: UserPermission[];
|
|
77
|
+
};
|
|
78
|
+
}>;
|
|
79
|
+
/**
|
|
80
|
+
* Finalizes login after a challenge
|
|
81
|
+
*/
|
|
82
|
+
declare function finalizeLogin(userId: string, flags: SessionFlags): Promise<{
|
|
83
|
+
session: {
|
|
84
|
+
[x: string]: any;
|
|
85
|
+
id: string;
|
|
86
|
+
createdAt: Date;
|
|
87
|
+
updatedAt: Date | null;
|
|
88
|
+
userId: string;
|
|
89
|
+
active_organization_id: string | null;
|
|
90
|
+
expiresAt: Date;
|
|
91
|
+
} | null;
|
|
92
|
+
user: {
|
|
93
|
+
id: string;
|
|
94
|
+
email: string;
|
|
95
|
+
name: string;
|
|
96
|
+
password: string | null;
|
|
97
|
+
image: string | null;
|
|
98
|
+
recovery_code: Buffer<ArrayBufferLike>;
|
|
99
|
+
emailVerifiedAt: Date | null;
|
|
100
|
+
createdAt: Date;
|
|
101
|
+
updatedAt: Date | null;
|
|
102
|
+
} | null;
|
|
103
|
+
}>;
|
|
104
|
+
/**
|
|
105
|
+
* Sign Out
|
|
106
|
+
*/
|
|
107
|
+
declare function signOut(): Promise<void>;
|
|
108
|
+
//#endregion
|
|
109
|
+
export { checkSecurity, finalizeLogin, performFullUserAugmentation, registerAuthValidator, registerEmailVerificationValidator, registerPasswordResetValidator, registerSecurityRequirement, runEmailVerificationValidators, runPasswordResetValidators, signIn, signOut, signUp };
|
|
110
|
+
//# sourceMappingURL=logic.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logic.d.mts","names":[],"sources":["../../../src/core/auth/logic.ts"],"mappings":";;;;;;;;;KAyHK,aAAA,IAAiB,MAAA,aAAmB,OAAA,CAAQ,YAAA;;;;KAK5C,mBAAA,IACH,OAAA,EAAS,OAAA,EACT,IAAA,EAAM,QAAA,KACH,OAAA;EAAU,SAAA;EAAoB,QAAA;AAAA;;AAR0B;;KAaxD,sBAAA,IAA0B,MAAA,aAAmB,OAAA,CAAQ,YAAA;;;;KAKrD,0BAAA,IACH,MAAA,aACG,OAAA,CAAQ,YAAA;AAAA,iBA6BS,qBAAA,CAAsB,SAAA,EAAW,aAAA,GAAa,OAAA;AAAA,iBAI9C,8BAAA,CACpB,SAAA,EAAW,sBAAA,GAAsB,OAAA;AAAA,iBAKb,kCAAA,CACpB,SAAA,EAAW,0BAAA,GAA0B,OAAA;AAAA,iBAajB,2BAAA,CACpB,WAAA,EAAa,mBAAA,GAAmB,OAAA;AAAA,iBAKZ,0BAAA,CACpB,MAAA,WACC,OAAA,CAAQ,YAAA;AAAA,iBAQW,8BAAA,CACpB,MAAA,WACC,OAAA,CAAQ,YAAA;;;;AAnFgC;iBA+FrB,2BAAA,CACpB,IAAA,EAAM,IAAA,GACL,OAAA,CAAQ,QAAA;;;;iBAQW,aAAA,CACpB,OAAA,EAAS,OAAA,EACT,IAAA,EAAM,QAAA,EACN,aAAA,GAAgB,QAAA,IAChB,mBAAA,GAAsB,cAAA,IACtB,gBAAA,YAAyB,OAAA;;;;;;;;;;iBA+DL,MAAA,CAAO,IAAA,EAAM,UAAA,GAAa,OAAA,CAAQ,YAAA;;;AApIxD;iBAyKsB,MAAA,CAAO,IAAA,EAAM,aAAA,GAAa,OAAA;;;;;;;;;;;;;;;;;;;;;;;;;;AAjJhD;;iBAyLsB,aAAA,CAAc,MAAA,UAAgB,KAAA,EAAO,YAAA,GAAY,OAAA;;;;;;;;;;;;;;;;;;;;;;;;;iBAoBjD,OAAA,CAAA,GAAO,OAAA"}
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
"use server";
|
|
2
|
+
|
|
3
|
+
import { loginSchema, registerSchema } from "./validation.mjs";
|
|
4
|
+
import { eventBus } from "../event-bus.mjs";
|
|
5
|
+
import { db } from "../../server/database/inject.mjs";
|
|
6
|
+
import { permissionsTable, rolesTable, rolesToPermissionsTable, usersToPermissionsTable, usersToRolesTable } from "../../server/database/schema.mjs";
|
|
7
|
+
import { verifyPasswordHash, verifyPasswordStrength } from "../../server/auth/password.mjs";
|
|
8
|
+
import { createUser, getUserById, getUserFromEmail, getUserPasswordHash, verifyUsernameInput } from "../../server/auth/user.mjs";
|
|
9
|
+
import { augmentSession, augmentUser, registerIdentityAugmenter, registerPasswordResetSessionAugmenter, registerSessionAugmenter } from "./augment.mjs";
|
|
10
|
+
import { createEmailVerificationRequest, sendVerificationEmail, setEmailVerificationRequestCookie } from "./email-verification.mjs";
|
|
11
|
+
import { createSession, deleteSessionTokenCookie, generateSessionToken, getCurrentSession, invalidateSession, setSessionTokenCookie } from "./session.mjs";
|
|
12
|
+
import { eq, inArray } from "drizzle-orm";
|
|
13
|
+
|
|
14
|
+
//#region src/core/auth/logic.ts
|
|
15
|
+
/**
|
|
16
|
+
* Podstawowy moduł rozszerzający tożsamość dla ról i uprawnień
|
|
17
|
+
*/
|
|
18
|
+
async function coreRbacAugmenter(user) {
|
|
19
|
+
try {
|
|
20
|
+
const roles = (await db.select({ name: rolesTable.name }).from(usersToRolesTable).innerJoin(rolesTable, eq(usersToRolesTable.roleId, rolesTable.id)).where(eq(usersToRolesTable.userId, user.id))).map((r) => r.name);
|
|
21
|
+
const directPerms = (await db.select({ name: permissionsTable.name }).from(usersToPermissionsTable).innerJoin(permissionsTable, eq(usersToPermissionsTable.permissionId, permissionsTable.id)).where(eq(usersToPermissionsTable.userId, user.id))).map((p) => p.name);
|
|
22
|
+
let rolePerms = [];
|
|
23
|
+
if (roles.length > 0) {
|
|
24
|
+
const roleIds = (await db.select({ id: rolesTable.id }).from(rolesTable).where(inArray(rolesTable.name, roles))).map((r) => r.id);
|
|
25
|
+
if (roleIds.length > 0) rolePerms = (await db.select({ name: permissionsTable.name }).from(rolesToPermissionsTable).innerJoin(permissionsTable, eq(rolesToPermissionsTable.permissionId, permissionsTable.id)).where(inArray(rolesToPermissionsTable.roleId, roleIds))).map((p) => p.name);
|
|
26
|
+
}
|
|
27
|
+
return {
|
|
28
|
+
roles,
|
|
29
|
+
permissions: Array.from(new Set([...directPerms, ...rolePerms]))
|
|
30
|
+
};
|
|
31
|
+
} catch (error) {
|
|
32
|
+
console.error("[Auth:RBAC] Failed to augment user:", error);
|
|
33
|
+
return {
|
|
34
|
+
roles: [],
|
|
35
|
+
permissions: []
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
const globalForAuth = globalThis;
|
|
40
|
+
const authValidators = globalForAuth.__WINKLY_AUTH_VALIDATORS__ ?? /* @__PURE__ */ new Set();
|
|
41
|
+
const securityRequirements = globalForAuth.__WINKLY_SECURITY_REQUIREMENTS__ ?? /* @__PURE__ */ new Set();
|
|
42
|
+
const passwordResetValidators = globalForAuth.__WINKLY_PASSWORD_RESET_VALIDATORS__ ?? /* @__PURE__ */ new Set();
|
|
43
|
+
const emailVerificationValidators = globalForAuth.__WINKLY_EMAIL_VERIFICATION_VALIDATORS__ ?? /* @__PURE__ */ new Set();
|
|
44
|
+
globalForAuth.__WINKLY_AUTH_VALIDATORS__ = authValidators;
|
|
45
|
+
globalForAuth.__WINKLY_SECURITY_REQUIREMENTS__ = securityRequirements;
|
|
46
|
+
globalForAuth.__WINKLY_PASSWORD_RESET_VALIDATORS__ = passwordResetValidators;
|
|
47
|
+
globalForAuth.__WINKLY_EMAIL_VERIFICATION_VALIDATORS__ = emailVerificationValidators;
|
|
48
|
+
async function registerAuthValidator(validator) {
|
|
49
|
+
authValidators.add(validator);
|
|
50
|
+
}
|
|
51
|
+
async function registerPasswordResetValidator(validator) {
|
|
52
|
+
passwordResetValidators.add(validator);
|
|
53
|
+
}
|
|
54
|
+
async function registerEmailVerificationValidator(validator) {
|
|
55
|
+
emailVerificationValidators.add(validator);
|
|
56
|
+
}
|
|
57
|
+
async function registerSecurityRequirement(requirement) {
|
|
58
|
+
securityRequirements.add(requirement);
|
|
59
|
+
}
|
|
60
|
+
async function runPasswordResetValidators(userId) {
|
|
61
|
+
for (const validator of passwordResetValidators) {
|
|
62
|
+
const interception = await validator(userId);
|
|
63
|
+
if (interception) return interception;
|
|
64
|
+
}
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
async function runEmailVerificationValidators(userId) {
|
|
68
|
+
for (const validator of emailVerificationValidators) {
|
|
69
|
+
const interception = await validator(userId);
|
|
70
|
+
if (interception) return interception;
|
|
71
|
+
}
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Augments a base user with data from all registered modules.
|
|
76
|
+
* This is now just a wrapper that includes core RBAC data.
|
|
77
|
+
*/
|
|
78
|
+
async function performFullUserAugmentation(user) {
|
|
79
|
+
return await augmentUser(user, await coreRbacAugmenter(user));
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Checks if the current session satisfies all registered security requirements.
|
|
83
|
+
*/
|
|
84
|
+
async function checkSecurity(session, user, requiredRoles, requiredPermissions, fallbackRedirect) {
|
|
85
|
+
if (!user) {
|
|
86
|
+
console.warn("User is required for security check");
|
|
87
|
+
return {
|
|
88
|
+
satisfied: false,
|
|
89
|
+
redirect: fallbackRedirect ?? "/signin"
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
const userRoles = Array.isArray(user.roles) ? user.roles : [];
|
|
93
|
+
const userPermissions = Array.isArray(user.permissions) ? user.permissions : [];
|
|
94
|
+
if (requiredRoles && requiredRoles.length > 0) {
|
|
95
|
+
if (!requiredRoles.some((role) => userRoles.includes(role))) {
|
|
96
|
+
console.warn(`User lacks required roles: ${requiredRoles.join(", ")}`);
|
|
97
|
+
return {
|
|
98
|
+
satisfied: false,
|
|
99
|
+
redirect: fallbackRedirect
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
if (requiredPermissions && requiredPermissions.length > 0) {
|
|
104
|
+
if (!requiredPermissions.every((perm) => userPermissions.includes(perm))) {
|
|
105
|
+
console.warn(`User lacks required permissions: ${requiredPermissions.join(", ")}`);
|
|
106
|
+
return {
|
|
107
|
+
satisfied: false,
|
|
108
|
+
redirect: fallbackRedirect
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
if (securityRequirements) for (const requirement of securityRequirements) try {
|
|
113
|
+
const result = await requirement(session, user);
|
|
114
|
+
if (result && !result.satisfied) return {
|
|
115
|
+
...result,
|
|
116
|
+
redirect: result.redirect ?? fallbackRedirect
|
|
117
|
+
};
|
|
118
|
+
} catch (error) {
|
|
119
|
+
console.error("[Auth:Security] Requirement failed:", error);
|
|
120
|
+
}
|
|
121
|
+
return { satisfied: true };
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Sign In Logic
|
|
125
|
+
*/
|
|
126
|
+
async function signIn(data) {
|
|
127
|
+
const { email, password } = await loginSchema.parseAsync(data);
|
|
128
|
+
const user = await getUserFromEmail(email);
|
|
129
|
+
if (!user) return {
|
|
130
|
+
status: "ERROR",
|
|
131
|
+
message: "Invalid email or password"
|
|
132
|
+
};
|
|
133
|
+
const passwordHash = await getUserPasswordHash(user.id);
|
|
134
|
+
if (!passwordHash || !await verifyPasswordHash(passwordHash, password)) return {
|
|
135
|
+
status: "ERROR",
|
|
136
|
+
message: "Invalid email or password"
|
|
137
|
+
};
|
|
138
|
+
for (const validator of authValidators) {
|
|
139
|
+
const interception = await validator(user.id);
|
|
140
|
+
if (interception) return interception;
|
|
141
|
+
}
|
|
142
|
+
const sessionFlags = {};
|
|
143
|
+
const sessionToken = await generateSessionToken();
|
|
144
|
+
const session = await createSession(sessionToken, user.id, sessionFlags);
|
|
145
|
+
await setSessionTokenCookie(sessionToken, session.expiresAt);
|
|
146
|
+
const fullUser = await performFullUserAugmentation(user);
|
|
147
|
+
await eventBus.publish("auth:session-created", {
|
|
148
|
+
session,
|
|
149
|
+
user: fullUser
|
|
150
|
+
});
|
|
151
|
+
return {
|
|
152
|
+
status: "SUCCESS",
|
|
153
|
+
session: { ...session },
|
|
154
|
+
user: { ...fullUser }
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Sign Up Logic
|
|
159
|
+
*/
|
|
160
|
+
async function signUp(data) {
|
|
161
|
+
const { email, username, password } = registerSchema.parse(data);
|
|
162
|
+
if (!await verifyUsernameInput(username)) throw new Error("Invalid username");
|
|
163
|
+
if (!await verifyPasswordStrength(password)) throw new Error("Weak password");
|
|
164
|
+
const user = await createUser(email, username, password);
|
|
165
|
+
const verificationRequest = await createEmailVerificationRequest(user.id, user.email);
|
|
166
|
+
await sendVerificationEmail(verificationRequest.email, verificationRequest.code);
|
|
167
|
+
await setEmailVerificationRequestCookie(verificationRequest);
|
|
168
|
+
const sessionFlags = {};
|
|
169
|
+
const sessionToken = await generateSessionToken();
|
|
170
|
+
const session = await createSession(sessionToken, user.id, sessionFlags);
|
|
171
|
+
await setSessionTokenCookie(sessionToken, session.expiresAt);
|
|
172
|
+
const fullUser = await performFullUserAugmentation(user);
|
|
173
|
+
await eventBus.publish("auth:session-created", {
|
|
174
|
+
session,
|
|
175
|
+
user: fullUser
|
|
176
|
+
});
|
|
177
|
+
return {
|
|
178
|
+
session: { ...session },
|
|
179
|
+
user: { ...fullUser }
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Finalizes login after a challenge
|
|
184
|
+
*/
|
|
185
|
+
async function finalizeLogin(userId, flags) {
|
|
186
|
+
const sessionToken = await generateSessionToken();
|
|
187
|
+
const session = await createSession(sessionToken, userId, flags);
|
|
188
|
+
await setSessionTokenCookie(sessionToken, session.expiresAt);
|
|
189
|
+
const user = await getUserById(userId);
|
|
190
|
+
if (user) await eventBus.publish("auth:session-created", {
|
|
191
|
+
session,
|
|
192
|
+
user
|
|
193
|
+
});
|
|
194
|
+
return {
|
|
195
|
+
session: session ? { ...session } : null,
|
|
196
|
+
user: user ? { ...user } : null
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Sign Out
|
|
201
|
+
*/
|
|
202
|
+
async function signOut() {
|
|
203
|
+
const { session, user } = await getCurrentSession();
|
|
204
|
+
if (session) {
|
|
205
|
+
if (user) await eventBus.publish("auth:signed-out", { userId: user.id });
|
|
206
|
+
await invalidateSession(session.id);
|
|
207
|
+
await deleteSessionTokenCookie();
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
//#endregion
|
|
212
|
+
export { checkSecurity, finalizeLogin, performFullUserAugmentation, registerAuthValidator, registerEmailVerificationValidator, registerPasswordResetValidator, registerSecurityRequirement, runEmailVerificationValidators, runPasswordResetValidators, signIn, signOut, signUp };
|
|
213
|
+
//# sourceMappingURL=logic.mjs.map
|