@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.
Files changed (190) hide show
  1. package/dist/_virtual/_rolldown/runtime.cjs +29 -0
  2. package/dist/_virtual/_rolldown/runtime.mjs +18 -0
  3. package/dist/core/auth/augment.cjs +71 -0
  4. package/dist/core/auth/augment.d.cts +20 -0
  5. package/dist/core/auth/augment.d.cts.map +1 -0
  6. package/dist/core/auth/augment.d.mts +20 -0
  7. package/dist/core/auth/augment.d.mts.map +1 -0
  8. package/dist/core/auth/augment.mjs +66 -0
  9. package/dist/core/auth/augment.mjs.map +1 -0
  10. package/dist/core/auth/email-verification.cjs +99 -0
  11. package/dist/core/auth/email-verification.d.cts +62 -0
  12. package/dist/core/auth/email-verification.d.cts.map +1 -0
  13. package/dist/core/auth/email-verification.d.mts +62 -0
  14. package/dist/core/auth/email-verification.d.mts.map +1 -0
  15. package/dist/core/auth/email-verification.mjs +92 -0
  16. package/dist/core/auth/email-verification.mjs.map +1 -0
  17. package/dist/core/auth/logic.cjs +224 -0
  18. package/dist/core/auth/logic.d.cts +110 -0
  19. package/dist/core/auth/logic.d.cts.map +1 -0
  20. package/dist/core/auth/logic.d.mts +110 -0
  21. package/dist/core/auth/logic.d.mts.map +1 -0
  22. package/dist/core/auth/logic.mjs +213 -0
  23. package/dist/core/auth/logic.mjs.map +1 -0
  24. package/dist/core/auth/password-reset.cjs +118 -0
  25. package/dist/core/auth/password-reset.d.cts +39 -0
  26. package/dist/core/auth/password-reset.d.cts.map +1 -0
  27. package/dist/core/auth/password-reset.d.mts +39 -0
  28. package/dist/core/auth/password-reset.d.mts.map +1 -0
  29. package/dist/core/auth/password-reset.mjs +111 -0
  30. package/dist/core/auth/password-reset.mjs.map +1 -0
  31. package/dist/core/auth/rbac.cjs +118 -0
  32. package/dist/core/auth/rbac.d.cts +61 -0
  33. package/dist/core/auth/rbac.d.cts.map +1 -0
  34. package/dist/core/auth/rbac.d.mts +61 -0
  35. package/dist/core/auth/rbac.d.mts.map +1 -0
  36. package/dist/core/auth/rbac.mjs +104 -0
  37. package/dist/core/auth/rbac.mjs.map +1 -0
  38. package/dist/core/auth/session.cjs +161 -0
  39. package/dist/core/auth/session.d.cts +54 -0
  40. package/dist/core/auth/session.d.cts.map +1 -0
  41. package/dist/core/auth/session.d.mts +54 -0
  42. package/dist/core/auth/session.d.mts.map +1 -0
  43. package/dist/core/auth/session.mjs +150 -0
  44. package/dist/core/auth/session.mjs.map +1 -0
  45. package/dist/core/auth/types.d.cts +55 -0
  46. package/dist/core/auth/types.d.cts.map +1 -0
  47. package/dist/core/auth/types.d.mts +55 -0
  48. package/dist/core/auth/types.d.mts.map +1 -0
  49. package/dist/core/auth/utils/encode.cjs +27 -0
  50. package/dist/core/auth/utils/encode.d.cts +15 -0
  51. package/dist/core/auth/utils/encode.d.cts.map +1 -0
  52. package/dist/core/auth/utils/encode.d.mts +15 -0
  53. package/dist/core/auth/utils/encode.d.mts.map +1 -0
  54. package/dist/core/auth/utils/encode.mjs +26 -0
  55. package/dist/core/auth/utils/encode.mjs.map +1 -0
  56. package/dist/core/auth/utils/encryption.cjs +67 -0
  57. package/dist/core/auth/utils/encryption.d.cts +28 -0
  58. package/dist/core/auth/utils/encryption.d.cts.map +1 -0
  59. package/dist/core/auth/utils/encryption.d.mts +28 -0
  60. package/dist/core/auth/utils/encryption.d.mts.map +1 -0
  61. package/dist/core/auth/utils/encryption.mjs +64 -0
  62. package/dist/core/auth/utils/encryption.mjs.map +1 -0
  63. package/dist/core/auth/validation.cjs +39 -0
  64. package/dist/core/auth/validation.d.cts +48 -0
  65. package/dist/core/auth/validation.d.cts.map +1 -0
  66. package/dist/core/auth/validation.d.mts +48 -0
  67. package/dist/core/auth/validation.d.mts.map +1 -0
  68. package/dist/core/auth/validation.mjs +31 -0
  69. package/dist/core/auth/validation.mjs.map +1 -0
  70. package/dist/core/bootstrap.cjs +32 -0
  71. package/dist/core/bootstrap.d.cts +5 -0
  72. package/dist/core/bootstrap.d.cts.map +1 -0
  73. package/dist/core/bootstrap.d.mts +5 -0
  74. package/dist/core/bootstrap.d.mts.map +1 -0
  75. package/dist/core/bootstrap.mjs +33 -0
  76. package/dist/core/bootstrap.mjs.map +1 -0
  77. package/dist/core/config.cjs +6 -0
  78. package/dist/core/config.d.cts +11 -0
  79. package/dist/core/config.d.cts.map +1 -0
  80. package/dist/core/config.d.mts +11 -0
  81. package/dist/core/config.d.mts.map +1 -0
  82. package/dist/core/config.mjs +6 -0
  83. package/dist/core/config.mjs.map +1 -0
  84. package/dist/core/config.server.cjs +60 -0
  85. package/dist/core/config.server.d.cts +16 -0
  86. package/dist/core/config.server.d.cts.map +1 -0
  87. package/dist/core/config.server.d.mts +16 -0
  88. package/dist/core/config.server.d.mts.map +1 -0
  89. package/dist/core/config.server.mjs +57 -0
  90. package/dist/core/config.server.mjs.map +1 -0
  91. package/dist/core/event-bus.cjs +48 -0
  92. package/dist/core/event-bus.d.cts +17 -0
  93. package/dist/core/event-bus.d.cts.map +1 -0
  94. package/dist/core/event-bus.d.mts +17 -0
  95. package/dist/core/event-bus.d.mts.map +1 -0
  96. package/dist/core/event-bus.mjs +48 -0
  97. package/dist/core/event-bus.mjs.map +1 -0
  98. package/dist/core/filesystem/service.cjs +43 -0
  99. package/dist/core/filesystem/service.d.cts +19 -0
  100. package/dist/core/filesystem/service.d.cts.map +1 -0
  101. package/dist/core/filesystem/service.d.mts +19 -0
  102. package/dist/core/filesystem/service.d.mts.map +1 -0
  103. package/dist/core/filesystem/service.mjs +43 -0
  104. package/dist/core/filesystem/service.mjs.map +1 -0
  105. package/dist/core/filesystem/types.d.cts +22 -0
  106. package/dist/core/filesystem/types.d.cts.map +1 -0
  107. package/dist/core/filesystem/types.d.mts +22 -0
  108. package/dist/core/filesystem/types.d.mts.map +1 -0
  109. package/dist/core/notifications/actions.cjs +36 -0
  110. package/dist/core/notifications/actions.d.cts +58 -0
  111. package/dist/core/notifications/actions.d.cts.map +1 -0
  112. package/dist/core/notifications/actions.d.mts +58 -0
  113. package/dist/core/notifications/actions.d.mts.map +1 -0
  114. package/dist/core/notifications/actions.mjs +33 -0
  115. package/dist/core/notifications/actions.mjs.map +1 -0
  116. package/dist/core/notifications/index.cjs +2 -0
  117. package/dist/core/notifications/index.mjs +4 -0
  118. package/dist/core/notifications/service.cjs +30 -0
  119. package/dist/core/notifications/service.d.cts +9 -0
  120. package/dist/core/notifications/service.d.cts.map +1 -0
  121. package/dist/core/notifications/service.d.mts +9 -0
  122. package/dist/core/notifications/service.d.mts.map +1 -0
  123. package/dist/core/notifications/service.mjs +31 -0
  124. package/dist/core/notifications/service.mjs.map +1 -0
  125. package/dist/core/notifications/types.d.cts +21 -0
  126. package/dist/core/notifications/types.d.cts.map +1 -0
  127. package/dist/core/notifications/types.d.mts +21 -0
  128. package/dist/core/notifications/types.d.mts.map +1 -0
  129. package/dist/core/setup.cjs +25 -0
  130. package/dist/core/setup.d.cts +9 -0
  131. package/dist/core/setup.d.cts.map +1 -0
  132. package/dist/core/setup.d.mts +9 -0
  133. package/dist/core/setup.d.mts.map +1 -0
  134. package/dist/core/setup.mjs +25 -0
  135. package/dist/core/setup.mjs.map +1 -0
  136. package/dist/core/types.d.cts +13 -0
  137. package/dist/core/types.d.cts.map +1 -0
  138. package/dist/core/types.d.mts +13 -0
  139. package/dist/core/types.d.mts.map +1 -0
  140. package/dist/index.cjs +30 -0
  141. package/dist/index.d.cts +8 -0
  142. package/dist/index.d.mts +8 -0
  143. package/dist/index.mjs +6 -0
  144. package/dist/server/auth/email.cjs +24 -0
  145. package/dist/server/auth/email.d.cts +13 -0
  146. package/dist/server/auth/email.d.cts.map +1 -0
  147. package/dist/server/auth/email.d.mts +13 -0
  148. package/dist/server/auth/email.d.mts.map +1 -0
  149. package/dist/server/auth/email.mjs +23 -0
  150. package/dist/server/auth/email.mjs.map +1 -0
  151. package/dist/server/auth/password.cjs +37 -0
  152. package/dist/server/auth/password.d.cts +23 -0
  153. package/dist/server/auth/password.d.cts.map +1 -0
  154. package/dist/server/auth/password.d.mts +23 -0
  155. package/dist/server/auth/password.d.mts.map +1 -0
  156. package/dist/server/auth/password.mjs +34 -0
  157. package/dist/server/auth/password.mjs.map +1 -0
  158. package/dist/server/auth/user.cjs +165 -0
  159. package/dist/server/auth/user.d.cts +58 -0
  160. package/dist/server/auth/user.d.cts.map +1 -0
  161. package/dist/server/auth/user.d.mts +58 -0
  162. package/dist/server/auth/user.d.mts.map +1 -0
  163. package/dist/server/auth/user.mjs +153 -0
  164. package/dist/server/auth/user.mjs.map +1 -0
  165. package/dist/server/database/inject.cjs +24 -0
  166. package/dist/server/database/inject.d.cts +15 -0
  167. package/dist/server/database/inject.d.cts.map +1 -0
  168. package/dist/server/database/inject.d.mts +15 -0
  169. package/dist/server/database/inject.d.mts.map +1 -0
  170. package/dist/server/database/inject.mjs +23 -0
  171. package/dist/server/database/inject.mjs.map +1 -0
  172. package/dist/server/database/schema.cjs +163 -0
  173. package/dist/server/database/schema.d.cts +2962 -0
  174. package/dist/server/database/schema.d.cts.map +1 -0
  175. package/dist/server/database/schema.d.mts +2962 -0
  176. package/dist/server/database/schema.d.mts.map +1 -0
  177. package/dist/server/database/schema.mjs +151 -0
  178. package/dist/server/database/schema.mjs.map +1 -0
  179. package/dist/server/emails/index.cjs +32 -0
  180. package/dist/server/emails/index.d.cts +26 -0
  181. package/dist/server/emails/index.d.cts.map +1 -0
  182. package/dist/server/emails/index.d.mts +26 -0
  183. package/dist/server/emails/index.d.mts.map +1 -0
  184. package/dist/server/emails/index.mjs +29 -0
  185. package/dist/server/emails/index.mjs.map +1 -0
  186. package/dist/server.cjs +145 -0
  187. package/dist/server.d.cts +26 -0
  188. package/dist/server.d.mts +26 -0
  189. package/dist/server.mjs +23 -0
  190. 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