@arch-cadre/core 0.0.56 → 0.0.57

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 (297) hide show
  1. package/dist/_virtual/_rolldown/runtime.cjs +1 -0
  2. package/dist/_virtual/_rolldown/runtime.mjs +1 -0
  3. package/dist/core/auth/augment.cjs +1 -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 +2 -0
  9. package/dist/core/auth/augment.mjs.map +1 -0
  10. package/dist/core/auth/email-verification.cjs +1 -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 +2 -0
  16. package/dist/core/auth/email-verification.mjs.map +1 -0
  17. package/dist/core/auth/logic.cjs +1 -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 +2 -0
  23. package/dist/core/auth/logic.mjs.map +1 -0
  24. package/dist/core/auth/password-reset.cjs +1 -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 +2 -0
  30. package/dist/core/auth/password-reset.mjs.map +1 -0
  31. package/dist/core/auth/rbac.cjs +1 -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 +2 -0
  37. package/dist/core/auth/rbac.mjs.map +1 -0
  38. package/dist/core/auth/session.cjs +1 -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 +2 -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 +1 -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 +2 -0
  55. package/dist/core/auth/utils/encode.mjs.map +1 -0
  56. package/dist/core/auth/utils/encryption.cjs +1 -0
  57. package/dist/core/auth/utils/{encryption.d.ts → encryption.d.cts} +8 -5
  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 +2 -0
  62. package/dist/core/auth/utils/encryption.mjs.map +1 -0
  63. package/dist/core/auth/validation.cjs +1 -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 +2 -0
  69. package/dist/core/auth/validation.mjs.map +1 -0
  70. package/dist/core/bootstrap.cjs +1 -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 +2 -0
  76. package/dist/core/bootstrap.mjs.map +1 -0
  77. package/dist/core/config.cjs +1 -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 +2 -0
  83. package/dist/core/config.mjs.map +1 -0
  84. package/dist/core/config.server.cjs +1 -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 +2 -0
  90. package/dist/core/config.server.mjs.map +1 -0
  91. package/dist/core/event-bus.cjs +1 -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 +2 -0
  97. package/dist/core/event-bus.mjs.map +1 -0
  98. package/dist/core/filesystem/index.cjs +1 -0
  99. package/dist/core/filesystem/index.mjs +2 -0
  100. package/dist/core/filesystem/index.mjs.map +1 -0
  101. package/dist/core/filesystem/providers/local.cjs +1 -0
  102. package/dist/core/filesystem/providers/local.mjs +2 -0
  103. package/dist/core/filesystem/providers/local.mjs.map +1 -0
  104. package/dist/core/filesystem/service.cjs +1 -0
  105. package/dist/core/filesystem/service.d.cts +19 -0
  106. package/dist/core/filesystem/service.d.cts.map +1 -0
  107. package/dist/core/filesystem/service.d.mts +19 -0
  108. package/dist/core/filesystem/service.d.mts.map +1 -0
  109. package/dist/core/filesystem/service.mjs +2 -0
  110. package/dist/core/filesystem/service.mjs.map +1 -0
  111. package/dist/core/filesystem/types.d.cts +22 -0
  112. package/dist/core/filesystem/types.d.cts.map +1 -0
  113. package/dist/core/filesystem/types.d.mts +22 -0
  114. package/dist/core/filesystem/types.d.mts.map +1 -0
  115. package/dist/core/notifications/actions.cjs +1 -0
  116. package/dist/core/notifications/actions.d.cts +58 -0
  117. package/dist/core/notifications/actions.d.cts.map +1 -0
  118. package/dist/core/notifications/actions.d.mts +58 -0
  119. package/dist/core/notifications/actions.d.mts.map +1 -0
  120. package/dist/core/notifications/actions.mjs +2 -0
  121. package/dist/core/notifications/actions.mjs.map +1 -0
  122. package/dist/core/notifications/index.cjs +1 -0
  123. package/dist/core/notifications/index.mjs +1 -0
  124. package/dist/core/notifications/service.cjs +1 -0
  125. package/dist/core/notifications/service.d.cts +9 -0
  126. package/dist/core/notifications/service.d.cts.map +1 -0
  127. package/dist/core/notifications/service.d.mts +9 -0
  128. package/dist/core/notifications/service.d.mts.map +1 -0
  129. package/dist/core/notifications/service.mjs +2 -0
  130. package/dist/core/notifications/service.mjs.map +1 -0
  131. package/dist/core/notifications/types.d.cts +21 -0
  132. package/dist/core/notifications/types.d.cts.map +1 -0
  133. package/dist/core/notifications/types.d.mts +21 -0
  134. package/dist/core/notifications/types.d.mts.map +1 -0
  135. package/dist/core/setup.cjs +1 -0
  136. package/dist/core/setup.d.cts +9 -0
  137. package/dist/core/setup.d.cts.map +1 -0
  138. package/dist/core/setup.d.mts +9 -0
  139. package/dist/core/setup.d.mts.map +1 -0
  140. package/dist/core/setup.mjs +2 -0
  141. package/dist/core/setup.mjs.map +1 -0
  142. package/dist/core/types.d.cts +13 -0
  143. package/dist/core/types.d.cts.map +1 -0
  144. package/dist/core/types.d.mts +13 -0
  145. package/dist/core/types.d.mts.map +1 -0
  146. package/dist/index.cjs +1 -0
  147. package/dist/index.d.cts +8 -0
  148. package/dist/index.d.mts +8 -0
  149. package/dist/index.mjs +1 -0
  150. package/dist/server/auth/email.cjs +1 -0
  151. package/dist/server/auth/email.d.cts +13 -0
  152. package/dist/server/auth/email.d.cts.map +1 -0
  153. package/dist/server/auth/email.d.mts +13 -0
  154. package/dist/server/auth/email.d.mts.map +1 -0
  155. package/dist/server/auth/email.mjs +2 -0
  156. package/dist/server/auth/email.mjs.map +1 -0
  157. package/dist/server/auth/password.cjs +1 -0
  158. package/dist/server/auth/{password.d.ts → password.d.cts} +7 -4
  159. package/dist/server/auth/password.d.cts.map +1 -0
  160. package/dist/server/auth/{password.js → password.d.mts} +7 -14
  161. package/dist/server/auth/password.d.mts.map +1 -0
  162. package/dist/server/auth/password.mjs +2 -0
  163. package/dist/server/auth/password.mjs.map +1 -0
  164. package/dist/server/auth/user.cjs +1 -0
  165. package/dist/server/auth/user.d.cts +58 -0
  166. package/dist/server/auth/user.d.cts.map +1 -0
  167. package/dist/server/auth/user.d.mts +58 -0
  168. package/dist/server/auth/user.d.mts.map +1 -0
  169. package/dist/server/auth/user.mjs +2 -0
  170. package/dist/server/auth/user.mjs.map +1 -0
  171. package/dist/server/database/inject.cjs +1 -0
  172. package/dist/server/database/inject.d.cts +15 -0
  173. package/dist/server/database/inject.d.cts.map +1 -0
  174. package/dist/server/database/inject.d.mts +15 -0
  175. package/dist/server/database/inject.d.mts.map +1 -0
  176. package/dist/server/database/inject.mjs +2 -0
  177. package/dist/server/database/inject.mjs.map +1 -0
  178. package/dist/server/database/schema.cjs +1 -0
  179. package/dist/server/database/schema.d.cts +3065 -0
  180. package/dist/server/database/{schema.d.ts.map → schema.d.cts.map} +1 -1
  181. package/dist/server/database/schema.d.mts +3065 -0
  182. package/dist/server/database/schema.d.mts.map +1 -0
  183. package/dist/server/database/schema.mjs +2 -0
  184. package/dist/server/database/schema.mjs.map +1 -0
  185. package/dist/server/emails/index.cjs +1 -0
  186. package/dist/server/emails/index.d.cts +26 -0
  187. package/dist/server/emails/index.d.cts.map +1 -0
  188. package/dist/server/emails/index.d.mts +26 -0
  189. package/dist/server/emails/index.d.mts.map +1 -0
  190. package/dist/server/emails/index.mjs +2 -0
  191. package/dist/server/emails/index.mjs.map +1 -0
  192. package/dist/server.cjs +1 -0
  193. package/dist/server.d.cts +26 -0
  194. package/dist/server.d.mts +26 -0
  195. package/dist/server.mjs +1 -0
  196. package/package.json +15 -7
  197. package/dist/core/auth/augment.d.ts +0 -18
  198. package/dist/core/auth/augment.d.ts.map +0 -1
  199. package/dist/core/auth/augment.js +0 -45
  200. package/dist/core/auth/email-verification.d.ts +0 -58
  201. package/dist/core/auth/email-verification.d.ts.map +0 -1
  202. package/dist/core/auth/email-verification.js +0 -105
  203. package/dist/core/auth/events.d.ts +0 -53
  204. package/dist/core/auth/events.d.ts.map +0 -1
  205. package/dist/core/auth/events.js +0 -1
  206. package/dist/core/auth/logic.d.ts +0 -106
  207. package/dist/core/auth/logic.d.ts.map +0 -1
  208. package/dist/core/auth/logic.js +0 -245
  209. package/dist/core/auth/password-reset.d.ts +0 -35
  210. package/dist/core/auth/password-reset.d.ts.map +0 -1
  211. package/dist/core/auth/password-reset.js +0 -122
  212. package/dist/core/auth/rbac.d.ts +0 -56
  213. package/dist/core/auth/rbac.d.ts.map +0 -1
  214. package/dist/core/auth/rbac.js +0 -134
  215. package/dist/core/auth/session.d.ts +0 -50
  216. package/dist/core/auth/session.d.ts.map +0 -1
  217. package/dist/core/auth/session.js +0 -152
  218. package/dist/core/auth/types.d.ts +0 -52
  219. package/dist/core/auth/types.d.ts.map +0 -1
  220. package/dist/core/auth/types.js +0 -1
  221. package/dist/core/auth/utils/encode.d.ts +0 -12
  222. package/dist/core/auth/utils/encode.d.ts.map +0 -1
  223. package/dist/core/auth/utils/encode.js +0 -20
  224. package/dist/core/auth/utils/encryption.d.ts.map +0 -1
  225. package/dist/core/auth/utils/encryption.js +0 -62
  226. package/dist/core/auth/validation.d.ts +0 -44
  227. package/dist/core/auth/validation.d.ts.map +0 -1
  228. package/dist/core/auth/validation.js +0 -41
  229. package/dist/core/bootstrap.d.ts +0 -2
  230. package/dist/core/bootstrap.d.ts.map +0 -1
  231. package/dist/core/bootstrap.js +0 -51
  232. package/dist/core/config.d.ts +0 -9
  233. package/dist/core/config.d.ts.map +0 -1
  234. package/dist/core/config.js +0 -3
  235. package/dist/core/config.server.d.ts +0 -12
  236. package/dist/core/config.server.d.ts.map +0 -1
  237. package/dist/core/config.server.js +0 -61
  238. package/dist/core/event-bus.d.ts +0 -14
  239. package/dist/core/event-bus.d.ts.map +0 -1
  240. package/dist/core/event-bus.js +0 -51
  241. package/dist/core/filesystem/index.d.ts +0 -4
  242. package/dist/core/filesystem/index.d.ts.map +0 -1
  243. package/dist/core/filesystem/index.js +0 -10
  244. package/dist/core/filesystem/providers/local.d.ts +0 -8
  245. package/dist/core/filesystem/providers/local.d.ts.map +0 -1
  246. package/dist/core/filesystem/providers/local.js +0 -42
  247. package/dist/core/filesystem/service.d.ts +0 -16
  248. package/dist/core/filesystem/service.d.ts.map +0 -1
  249. package/dist/core/filesystem/service.js +0 -51
  250. package/dist/core/filesystem/types.d.ts +0 -19
  251. package/dist/core/filesystem/types.d.ts.map +0 -1
  252. package/dist/core/filesystem/types.js +0 -1
  253. package/dist/core/notifications/actions.d.ts +0 -54
  254. package/dist/core/notifications/actions.d.ts.map +0 -1
  255. package/dist/core/notifications/actions.js +0 -43
  256. package/dist/core/notifications/index.d.ts +0 -4
  257. package/dist/core/notifications/index.d.ts.map +0 -1
  258. package/dist/core/notifications/index.js +0 -3
  259. package/dist/core/notifications/service.d.ts +0 -7
  260. package/dist/core/notifications/service.d.ts.map +0 -1
  261. package/dist/core/notifications/service.js +0 -32
  262. package/dist/core/notifications/types.d.ts +0 -17
  263. package/dist/core/notifications/types.d.ts.map +0 -1
  264. package/dist/core/notifications/types.js +0 -1
  265. package/dist/core/setup.d.ts +0 -6
  266. package/dist/core/setup.d.ts.map +0 -1
  267. package/dist/core/setup.js +0 -25
  268. package/dist/core/types.d.ts +0 -10
  269. package/dist/core/types.d.ts.map +0 -1
  270. package/dist/core/types.js +0 -1
  271. package/dist/index.d.ts +0 -8
  272. package/dist/index.d.ts.map +0 -1
  273. package/dist/index.js +0 -16
  274. package/dist/server/auth/email.d.ts +0 -10
  275. package/dist/server/auth/email.d.ts.map +0 -1
  276. package/dist/server/auth/email.js +0 -20
  277. package/dist/server/auth/password.d.ts.map +0 -1
  278. package/dist/server/auth/types.d.ts +0 -13
  279. package/dist/server/auth/types.d.ts.map +0 -1
  280. package/dist/server/auth/types.js +0 -1
  281. package/dist/server/auth/user.d.ts +0 -54
  282. package/dist/server/auth/user.d.ts.map +0 -1
  283. package/dist/server/auth/user.js +0 -222
  284. package/dist/server/database/inject.d.ts +0 -11
  285. package/dist/server/database/inject.d.ts.map +0 -1
  286. package/dist/server/database/inject.js +0 -29
  287. package/dist/server/database/schema.d.ts +0 -3056
  288. package/dist/server/database/schema.js +0 -205
  289. package/dist/server/database/types.d.ts +0 -12
  290. package/dist/server/database/types.d.ts.map +0 -1
  291. package/dist/server/database/types.js +0 -1
  292. package/dist/server/emails/index.d.ts +0 -23
  293. package/dist/server/emails/index.d.ts.map +0 -1
  294. package/dist/server/emails/index.js +0 -67
  295. package/dist/server.d.ts +0 -25
  296. package/dist/server.d.ts.map +0 -1
  297. package/dist/server.js +0 -32
@@ -0,0 +1,2 @@
1
+ "use server";import{db as e}from"../../server/database/inject.mjs";import{passwordResetSessionTable as t,userTable as n}from"../../server/database/schema.mjs";import{augmentPasswordResetSession as r}from"./augment.mjs";import{generateRandomOTP as i}from"./utils/encode.mjs";import{sendResetPassword as a}from"../../server/emails/index.mjs";import{performFullUserAugmentation as o}from"./logic.mjs";import{eq as s}from"drizzle-orm";import{sha256 as c}from"@oslojs/crypto/sha2";import{encodeHexLowerCase as l}from"@oslojs/encoding";import{addHours as u}from"date-fns";import{cookies as d}from"next/headers";async function f(n,r,a){let o=l(c(new TextEncoder().encode(n))),[s]=await e.insert(t).values({id:o,email:a,code:i(),expiresAt:new Date(u(new Date,1)),userId:r}).returning();return s}async function p(i){let a=l(c(new TextEncoder().encode(i))),[u]=await e.select({session:t,user:n}).from(t).innerJoin(n,s(t.userId,n.id)).where(s(t.id,a));if(!u||!u.user)return{session:null,user:null};let{session:d,user:f}=u;if(new Date>d.expiresAt)return await e.delete(t).where(s(t.id,d.id)),{session:null,user:null};let{password:p,recovery_code:m,...h}=f,g=await o(h);return{session:await r(d),user:g}}async function m(n){await e.update(t).set({emailVerified:!0}).where(s(t.id,n))}async function h(n){await e.delete(t).where(s(t.userId,n))}async function g(){let e=(await d()).get(`password_reset_session`)?.value??null;if(e===null)return{session:null,user:null};let t=await p(e);return t.session===null&&await v(),t}async function _(e,t){(await d()).set(`password_reset_session`,e,{expires:t,sameSite:`lax`,httpOnly:!0,path:`/`,secure:process.env.NODE_ENV===`production`})}async function v(){(await d()).delete(`password_reset_session`)}async function y(e,t){await a(e,t)}export{f as createPasswordResetSession,v as deletePasswordResetSessionTokenCookie,g as getCurrentPasswordResetSession,h as invalidateUserPasswordResetSessions,y as sendPasswordResetEmail,m as setPasswordResetSessionAsEmailVerified,_ as setPasswordResetSessionTokenCookie,p as validatePasswordResetSessionToken};
2
+ //# sourceMappingURL=password-reset.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"password-reset.mjs","names":[],"sources":["../../../src/core/auth/password-reset.ts"],"sourcesContent":["\"use server\";\n\nimport { sha256 } from \"@oslojs/crypto/sha2\";\nimport { encodeHexLowerCase } from \"@oslojs/encoding\";\nimport { addHours } from \"date-fns\";\nimport { eq } from \"drizzle-orm\";\nimport { cookies } from \"next/headers\";\nimport { db } from \"../../server/database/inject\";\nimport {\n passwordResetSessionTable,\n userTable,\n} from \"../../server/database/schema\";\nimport { sendResetPassword } from \"../../server/emails/index\";\nimport { augmentPasswordResetSession } from \"./augment\";\nimport { performFullUserAugmentation } from \"./logic\";\nimport type { PasswordResetAuthSession, PasswordResetSession } from \"./types\";\nimport { generateRandomOTP } from \"./utils/encode\";\n\n/**\n * Creates a new password reset session.\n */\nexport async function createPasswordResetSession(\n token: string,\n userId: string,\n email: string,\n): Promise<PasswordResetSession> {\n const sessionId = encodeHexLowerCase(sha256(new TextEncoder().encode(token)));\n\n const [session] = await db\n .insert(passwordResetSessionTable)\n .values({\n id: sessionId,\n email: email,\n code: generateRandomOTP(),\n expiresAt: new Date(addHours(new Date(), 1)),\n userId: userId,\n })\n .returning();\n\n return session;\n}\n\n/**\n * Validates the password reset session token and retrieves user data.\n * The user data is augmented by registered modules (e.g. 2FA).\n */\nexport async function validatePasswordResetSessionToken(\n token: string,\n): Promise<PasswordResetAuthSession> {\n const sessionId = encodeHexLowerCase(sha256(new TextEncoder().encode(token)));\n\n const [row] = await db\n .select({\n session: passwordResetSessionTable,\n user: userTable,\n })\n .from(passwordResetSessionTable)\n .innerJoin(userTable, eq(passwordResetSessionTable.userId, userTable.id))\n .where(eq(passwordResetSessionTable.id, sessionId));\n\n if (!row || !row.user) {\n return { session: null, user: null };\n }\n\n const { session: baseSession, user: baseUser } = row;\n\n // Check for expiration\n if (new Date() > baseSession.expiresAt) {\n await db\n .delete(passwordResetSessionTable)\n .where(eq(passwordResetSessionTable.id, baseSession.id));\n return { session: null, user: null };\n }\n\n // STRICTLY remove non-serializable and sensitive fields\n const { password, recovery_code, ...safeUser } = baseUser;\n\n // AUGMENT (EXTENSIBILITY POINTS)\n const user = await performFullUserAugmentation(safeUser as any);\n const session = await augmentPasswordResetSession(\n baseSession as PasswordResetSession,\n );\n\n return { session, user };\n}\n\n/**\n * Marks the password reset session as email verified.\n */\nexport async function setPasswordResetSessionAsEmailVerified(\n sessionId: string,\n): Promise<void> {\n await db\n .update(passwordResetSessionTable)\n .set({\n emailVerified: true,\n })\n .where(eq(passwordResetSessionTable.id, sessionId));\n}\n\n/**\n * Invalidates all password reset sessions for a user.\n */\nexport async function invalidateUserPasswordResetSessions(\n userId: string,\n): Promise<void> {\n await db\n .delete(passwordResetSessionTable)\n .where(eq(passwordResetSessionTable.userId, userId));\n}\n\n/**\n * Validates the current password reset session from cookies.\n */\nexport async function getCurrentPasswordResetSession(): Promise<PasswordResetAuthSession> {\n const cookieStore = await cookies();\n const token = cookieStore.get(\"password_reset_session\")?.value ?? null;\n\n if (token === null) {\n return { session: null, user: null };\n }\n\n const result = await validatePasswordResetSessionToken(token);\n\n if (result.session === null) {\n await deletePasswordResetSessionTokenCookie();\n }\n\n return result;\n}\n\n/**\n * Sets the password reset session token cookie.\n */\nexport async function setPasswordResetSessionTokenCookie(\n token: string,\n expiresAt: Date,\n): Promise<void> {\n const cookieStore = await cookies();\n\n cookieStore.set(\"password_reset_session\", token, {\n expires: expiresAt,\n sameSite: \"lax\",\n httpOnly: true,\n path: \"/\",\n secure: process.env.NODE_ENV === \"production\",\n });\n}\n\n/**\n * Deletes the password reset session token cookie.\n */\nexport async function deletePasswordResetSessionTokenCookie(): Promise<void> {\n const cookieStore = await cookies();\n cookieStore.delete(\"password_reset_session\");\n}\n\n/**\n * Sends a password reset email with the OTP code.\n */\nexport async function sendPasswordResetEmail(\n email: string,\n code: string,\n): Promise<void> {\n await sendResetPassword(email, code);\n}\n"],"mappings":"6lBAqBA,eAAsB,EACpB,EACA,EACA,EAC+B,CAC/B,IAAM,EAAY,EAAmB,EAAO,IAAI,aAAa,CAAC,OAAO,EAAM,CAAC,CAAC,CAEvE,CAAC,GAAW,MAAM,EACrB,OAAO,EAA0B,CACjC,OAAO,CACN,GAAI,EACG,QACP,KAAM,GAAmB,CACzB,UAAW,IAAI,KAAK,EAAS,IAAI,KAAQ,EAAE,CAAC,CACpC,SACT,CAAC,CACD,WAAW,CAEd,OAAO,EAOT,eAAsB,EACpB,EACmC,CACnC,IAAM,EAAY,EAAmB,EAAO,IAAI,aAAa,CAAC,OAAO,EAAM,CAAC,CAAC,CAEvE,CAAC,GAAO,MAAM,EACjB,OAAO,CACN,QAAS,EACT,KAAM,EACP,CAAC,CACD,KAAK,EAA0B,CAC/B,UAAU,EAAW,EAAG,EAA0B,OAAQ,EAAU,GAAG,CAAC,CACxE,MAAM,EAAG,EAA0B,GAAI,EAAU,CAAC,CAErD,GAAI,CAAC,GAAO,CAAC,EAAI,KACf,MAAO,CAAE,QAAS,KAAM,KAAM,KAAM,CAGtC,GAAM,CAAE,QAAS,EAAa,KAAM,GAAa,EAGjD,GAAI,IAAI,KAAS,EAAY,UAI3B,OAHA,MAAM,EACH,OAAO,EAA0B,CACjC,MAAM,EAAG,EAA0B,GAAI,EAAY,GAAG,CAAC,CACnD,CAAE,QAAS,KAAM,KAAM,KAAM,CAItC,GAAM,CAAE,WAAU,gBAAe,GAAG,GAAa,EAG3C,EAAO,MAAM,EAA4B,EAAgB,CAK/D,MAAO,CAAE,QAJO,MAAM,EACpB,EACD,CAEiB,OAAM,CAM1B,eAAsB,EACpB,EACe,CACf,MAAM,EACH,OAAO,EAA0B,CACjC,IAAI,CACH,cAAe,GAChB,CAAC,CACD,MAAM,EAAG,EAA0B,GAAI,EAAU,CAAC,CAMvD,eAAsB,EACpB,EACe,CACf,MAAM,EACH,OAAO,EAA0B,CACjC,MAAM,EAAG,EAA0B,OAAQ,EAAO,CAAC,CAMxD,eAAsB,GAAoE,CAExF,IAAM,GADc,MAAM,GAAS,EACT,IAAI,yBAAyB,EAAE,OAAS,KAElE,GAAI,IAAU,KACZ,MAAO,CAAE,QAAS,KAAM,KAAM,KAAM,CAGtC,IAAM,EAAS,MAAM,EAAkC,EAAM,CAM7D,OAJI,EAAO,UAAY,MACrB,MAAM,GAAuC,CAGxC,EAMT,eAAsB,EACpB,EACA,EACe,EACK,MAAM,GAAS,EAEvB,IAAI,yBAA0B,EAAO,CAC/C,QAAS,EACT,SAAU,MACV,SAAU,GACV,KAAM,IACN,OAAQ,QAAQ,IAAI,WAAa,aAClC,CAAC,CAMJ,eAAsB,GAAuD,EACvD,MAAM,GAAS,EACvB,OAAO,yBAAyB,CAM9C,eAAsB,EACpB,EACA,EACe,CACf,MAAM,EAAkB,EAAO,EAAK"}
@@ -0,0 +1 @@
1
+ "use server";require(`../../_virtual/_rolldown/runtime.cjs`);const e=require(`../../server/database/inject.cjs`),t=require(`../../server/database/schema.cjs`),n=require(`../notifications/service.cjs`);require(`../notifications/index.cjs`);let r=require(`drizzle-orm`);typeof window>`u`&&n.notificationService.init();async function i(){return await e.db.select().from(t.rolesTable).orderBy(t.rolesTable.name)}async function a(n){let[i]=await e.db.select().from(t.rolesTable).where((0,r.eq)(t.rolesTable.id,n));return i}async function o(n,r){return await e.db.insert(t.rolesTable).values({name:n,description:r}).returning()}async function s(n){return await e.db.delete(t.rolesTable).where((0,r.eq)(t.rolesTable.id,n))}async function c(){return await e.db.select().from(t.permissionsTable).orderBy(t.permissionsTable.name)}async function l(n,r){return await e.db.insert(t.permissionsTable).values({name:n,description:r}).returning()}async function u(n){return await e.db.delete(t.permissionsTable).where((0,r.eq)(t.permissionsTable.id,n))}async function d(n){return await e.db.select({id:t.permissionsTable.id,name:t.permissionsTable.name}).from(t.rolesToPermissionsTable).innerJoin(t.permissionsTable,(0,r.eq)(t.rolesToPermissionsTable.permissionId,t.permissionsTable.id)).where((0,r.eq)(t.rolesToPermissionsTable.roleId,n))}async function f(n,r){return await e.db.insert(t.rolesToPermissionsTable).values({roleId:n,permissionId:r}).onConflictDoNothing()}async function p(n,i){return await e.db.delete(t.rolesToPermissionsTable).where((0,r.and)((0,r.eq)(t.rolesToPermissionsTable.roleId,n),(0,r.eq)(t.rolesToPermissionsTable.permissionId,i)))}async function m(n,r){return await e.db.insert(t.usersToRolesTable).values({userId:n,roleId:r}).onConflictDoNothing()}async function h(n,i){return await e.db.delete(t.usersToRolesTable).where((0,r.and)((0,r.eq)(t.usersToRolesTable.userId,n),(0,r.eq)(t.usersToRolesTable.roleId,i)))}async function g(n,r){return await e.db.insert(t.usersToPermissionsTable).values({userId:n,permissionId:r}).onConflictDoNothing()}async function _(n,i){return await e.db.delete(t.usersToPermissionsTable).where((0,r.and)((0,r.eq)(t.usersToPermissionsTable.userId,n),(0,r.eq)(t.usersToPermissionsTable.permissionId,i)))}async function v(n){let i=await e.db.select({id:t.rolesTable.id,name:t.rolesTable.name}).from(t.usersToRolesTable).innerJoin(t.rolesTable,(0,r.eq)(t.usersToRolesTable.roleId,t.rolesTable.id)).where((0,r.eq)(t.usersToRolesTable.userId,n)),a=await e.db.select({id:t.permissionsTable.id,name:t.permissionsTable.name}).from(t.usersToPermissionsTable).innerJoin(t.permissionsTable,(0,r.eq)(t.usersToPermissionsTable.permissionId,t.permissionsTable.id)).where((0,r.eq)(t.usersToPermissionsTable.userId,n)),o=[];if(i.length>0){let n=i.map(e=>e.id);o=await e.db.select({id:t.permissionsTable.id,name:t.permissionsTable.name}).from(t.rolesToPermissionsTable).innerJoin(t.permissionsTable,(0,r.eq)(t.rolesToPermissionsTable.permissionId,t.permissionsTable.id)).where((0,r.inArray)(t.rolesToPermissionsTable.roleId,n))}let s=new Map;for(let e of[...a,...o])s.set(e.id,e);return{roles:i,directPermissions:a,effectivePermissions:Array.from(s.values())}}exports.assignPermissionToRole=f,exports.assignPermissionToUser=g,exports.assignRoleToUser=m,exports.createPermission=l,exports.createRole=o,exports.deletePermission=u,exports.deleteRole=s,exports.getPermissions=c,exports.getRoleById=a,exports.getRolePermissions=d,exports.getRoles=i,exports.getUserRbacData=v,exports.revokePermissionFromRole=p,exports.revokePermissionFromUser=_,exports.revokeRoleFromUser=h;
@@ -0,0 +1,61 @@
1
+ import * as pg from "pg";
2
+
3
+ //#region src/core/auth/rbac.d.ts
4
+ /**
5
+ * CORE RBAC LOGIC
6
+ * This file handles all database operations for Roles and Permissions.
7
+ */
8
+ declare function getRoles(): Promise<{
9
+ id: string;
10
+ name: string;
11
+ description: string | null;
12
+ }[]>;
13
+ declare function getRoleById(roleId: string): Promise<{
14
+ id: string;
15
+ name: string;
16
+ description: string | null;
17
+ }>;
18
+ declare function createRole(name: string, description?: string): Promise<{
19
+ id: string;
20
+ name: string;
21
+ description: string | null;
22
+ }[]>;
23
+ declare function deleteRole(roleId: string): Promise<pg.QueryResult<never>>;
24
+ declare function getPermissions(): Promise<{
25
+ id: string;
26
+ name: string;
27
+ description: string | null;
28
+ }[]>;
29
+ declare function createPermission(name: string, description?: string): Promise<{
30
+ id: string;
31
+ name: string;
32
+ description: string | null;
33
+ }[]>;
34
+ declare function deletePermission(permissionId: string): Promise<pg.QueryResult<never>>;
35
+ declare function getRolePermissions(roleId: string): Promise<{
36
+ id: string;
37
+ name: string;
38
+ }[]>;
39
+ declare function assignPermissionToRole(roleId: string, permissionId: string): Promise<pg.QueryResult<never>>;
40
+ declare function revokePermissionFromRole(roleId: string, permissionId: string): Promise<pg.QueryResult<never>>;
41
+ declare function assignRoleToUser(userId: string, roleId: string): Promise<pg.QueryResult<never>>;
42
+ declare function revokeRoleFromUser(userId: string, roleId: string): Promise<pg.QueryResult<never>>;
43
+ declare function assignPermissionToUser(userId: string, permissionId: string): Promise<pg.QueryResult<never>>;
44
+ declare function revokePermissionFromUser(userId: string, permissionId: string): Promise<pg.QueryResult<never>>;
45
+ declare function getUserRbacData(userId: string): Promise<{
46
+ roles: {
47
+ id: string;
48
+ name: string;
49
+ }[];
50
+ directPermissions: {
51
+ id: string;
52
+ name: string;
53
+ }[];
54
+ effectivePermissions: {
55
+ id: string;
56
+ name: string;
57
+ }[];
58
+ }>;
59
+ //#endregion
60
+ export { assignPermissionToRole, assignPermissionToUser, assignRoleToUser, createPermission, createRole, deletePermission, deleteRole, getPermissions, getRoleById, getRolePermissions, getRoles, getUserRbacData, revokePermissionFromRole, revokePermissionFromUser, revokeRoleFromUser };
61
+ //# sourceMappingURL=rbac.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rbac.d.cts","names":[],"sources":["../../../src/core/auth/rbac.ts"],"mappings":";;;;;;AAyBA;iBAAsB,QAAA,CAAA,GAAQ,OAAA;;;;;iBAIR,WAAA,CAAY,MAAA,WAAc,OAAA;;;;;iBAQ1B,UAAA,CAAW,IAAA,UAAc,WAAA,YAAoB,OAAA;;;;;iBAI7C,UAAA,CAAW,MAAA,WAAc,OAAA,CAAf,EAAA,CAAe,WAAA;AAAA,iBAMzB,cAAA,CAAA,GAAc,OAAA;;;;;iBAOd,gBAAA,CAAiB,IAAA,UAAc,WAAA,YAAoB,OAAA;;;;;iBAOnD,gBAAA,CAAiB,YAAA,WAAoB,OAAA,CAArB,EAAA,CAAqB,WAAA;AAAA,iBAQrC,kBAAA,CAAmB,MAAA,WAAc,OAAA;;;;iBAcjC,sBAAA,CACpB,MAAA,UACA,YAAA,WAAoB,OAAA,CAFsB,EAAA,CAEtB,WAAA;AAAA,iBAQA,wBAAA,CACpB,MAAA,UACA,YAAA,WAAoB,OAAA,CAFwB,EAAA,CAExB,WAAA;AAAA,iBAcA,gBAAA,CAAiB,MAAA,UAAgB,MAAA,WAAc,OAAA,CAA/B,EAAA,CAA+B,WAAA;AAAA,iBAO/C,kBAAA,CAAmB,MAAA,UAAgB,MAAA,WAAc,OAAA,CAA/B,EAAA,CAA+B,WAAA;AAAA,iBAWjD,sBAAA,CACpB,MAAA,UACA,YAAA,WAAoB,OAAA,CAFsB,EAAA,CAEtB,WAAA;AAAA,iBAQA,wBAAA,CACpB,MAAA,UACA,YAAA,WAAoB,OAAA,CAFwB,EAAA,CAExB,WAAA;AAAA,iBAYA,eAAA,CAAgB,MAAA,WAAc,OAAA"}
@@ -0,0 +1,61 @@
1
+ import * as pg from "pg";
2
+
3
+ //#region src/core/auth/rbac.d.ts
4
+ /**
5
+ * CORE RBAC LOGIC
6
+ * This file handles all database operations for Roles and Permissions.
7
+ */
8
+ declare function getRoles(): Promise<{
9
+ id: string;
10
+ name: string;
11
+ description: string | null;
12
+ }[]>;
13
+ declare function getRoleById(roleId: string): Promise<{
14
+ id: string;
15
+ name: string;
16
+ description: string | null;
17
+ }>;
18
+ declare function createRole(name: string, description?: string): Promise<{
19
+ id: string;
20
+ name: string;
21
+ description: string | null;
22
+ }[]>;
23
+ declare function deleteRole(roleId: string): Promise<pg.QueryResult<never>>;
24
+ declare function getPermissions(): Promise<{
25
+ id: string;
26
+ name: string;
27
+ description: string | null;
28
+ }[]>;
29
+ declare function createPermission(name: string, description?: string): Promise<{
30
+ id: string;
31
+ name: string;
32
+ description: string | null;
33
+ }[]>;
34
+ declare function deletePermission(permissionId: string): Promise<pg.QueryResult<never>>;
35
+ declare function getRolePermissions(roleId: string): Promise<{
36
+ id: string;
37
+ name: string;
38
+ }[]>;
39
+ declare function assignPermissionToRole(roleId: string, permissionId: string): Promise<pg.QueryResult<never>>;
40
+ declare function revokePermissionFromRole(roleId: string, permissionId: string): Promise<pg.QueryResult<never>>;
41
+ declare function assignRoleToUser(userId: string, roleId: string): Promise<pg.QueryResult<never>>;
42
+ declare function revokeRoleFromUser(userId: string, roleId: string): Promise<pg.QueryResult<never>>;
43
+ declare function assignPermissionToUser(userId: string, permissionId: string): Promise<pg.QueryResult<never>>;
44
+ declare function revokePermissionFromUser(userId: string, permissionId: string): Promise<pg.QueryResult<never>>;
45
+ declare function getUserRbacData(userId: string): Promise<{
46
+ roles: {
47
+ id: string;
48
+ name: string;
49
+ }[];
50
+ directPermissions: {
51
+ id: string;
52
+ name: string;
53
+ }[];
54
+ effectivePermissions: {
55
+ id: string;
56
+ name: string;
57
+ }[];
58
+ }>;
59
+ //#endregion
60
+ export { assignPermissionToRole, assignPermissionToUser, assignRoleToUser, createPermission, createRole, deletePermission, deleteRole, getPermissions, getRoleById, getRolePermissions, getRoles, getUserRbacData, revokePermissionFromRole, revokePermissionFromUser, revokeRoleFromUser };
61
+ //# sourceMappingURL=rbac.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rbac.d.mts","names":[],"sources":["../../../src/core/auth/rbac.ts"],"mappings":";;;;;;AAyBA;iBAAsB,QAAA,CAAA,GAAQ,OAAA;;;;;iBAIR,WAAA,CAAY,MAAA,WAAc,OAAA;;;;;iBAQ1B,UAAA,CAAW,IAAA,UAAc,WAAA,YAAoB,OAAA;;;;;iBAI7C,UAAA,CAAW,MAAA,WAAc,OAAA,CAAf,EAAA,CAAe,WAAA;AAAA,iBAMzB,cAAA,CAAA,GAAc,OAAA;;;;;iBAOd,gBAAA,CAAiB,IAAA,UAAc,WAAA,YAAoB,OAAA;;;;;iBAOnD,gBAAA,CAAiB,YAAA,WAAoB,OAAA,CAArB,EAAA,CAAqB,WAAA;AAAA,iBAQrC,kBAAA,CAAmB,MAAA,WAAc,OAAA;;;;iBAcjC,sBAAA,CACpB,MAAA,UACA,YAAA,WAAoB,OAAA,CAFsB,EAAA,CAEtB,WAAA;AAAA,iBAQA,wBAAA,CACpB,MAAA,UACA,YAAA,WAAoB,OAAA,CAFwB,EAAA,CAExB,WAAA;AAAA,iBAcA,gBAAA,CAAiB,MAAA,UAAgB,MAAA,WAAc,OAAA,CAA/B,EAAA,CAA+B,WAAA;AAAA,iBAO/C,kBAAA,CAAmB,MAAA,UAAgB,MAAA,WAAc,OAAA,CAA/B,EAAA,CAA+B,WAAA;AAAA,iBAWjD,sBAAA,CACpB,MAAA,UACA,YAAA,WAAoB,OAAA,CAFsB,EAAA,CAEtB,WAAA;AAAA,iBAQA,wBAAA,CACpB,MAAA,UACA,YAAA,WAAoB,OAAA,CAFwB,EAAA,CAExB,WAAA;AAAA,iBAYA,eAAA,CAAgB,MAAA,WAAc,OAAA"}
@@ -0,0 +1,2 @@
1
+ "use server";import{db as e}from"../../server/database/inject.mjs";import{permissionsTable as t,rolesTable as n,rolesToPermissionsTable as r,usersToPermissionsTable as i,usersToRolesTable as a}from"../../server/database/schema.mjs";import{notificationService as o}from"../notifications/service.mjs";import"../notifications/index.mjs";import{and as s,eq as c,inArray as l}from"drizzle-orm";typeof window>`u`&&o.init();async function u(){return await e.select().from(n).orderBy(n.name)}async function d(t){let[r]=await e.select().from(n).where(c(n.id,t));return r}async function f(t,r){return await e.insert(n).values({name:t,description:r}).returning()}async function p(t){return await e.delete(n).where(c(n.id,t))}async function m(){return await e.select().from(t).orderBy(t.name)}async function h(n,r){return await e.insert(t).values({name:n,description:r}).returning()}async function g(n){return await e.delete(t).where(c(t.id,n))}async function _(n){return await e.select({id:t.id,name:t.name}).from(r).innerJoin(t,c(r.permissionId,t.id)).where(c(r.roleId,n))}async function v(t,n){return await e.insert(r).values({roleId:t,permissionId:n}).onConflictDoNothing()}async function y(t,n){return await e.delete(r).where(s(c(r.roleId,t),c(r.permissionId,n)))}async function b(t,n){return await e.insert(a).values({userId:t,roleId:n}).onConflictDoNothing()}async function x(t,n){return await e.delete(a).where(s(c(a.userId,t),c(a.roleId,n)))}async function S(t,n){return await e.insert(i).values({userId:t,permissionId:n}).onConflictDoNothing()}async function C(t,n){return await e.delete(i).where(s(c(i.userId,t),c(i.permissionId,n)))}async function w(o){let s=await e.select({id:n.id,name:n.name}).from(a).innerJoin(n,c(a.roleId,n.id)).where(c(a.userId,o)),u=await e.select({id:t.id,name:t.name}).from(i).innerJoin(t,c(i.permissionId,t.id)).where(c(i.userId,o)),d=[];if(s.length>0){let n=s.map(e=>e.id);d=await e.select({id:t.id,name:t.name}).from(r).innerJoin(t,c(r.permissionId,t.id)).where(l(r.roleId,n))}let f=new Map;for(let e of[...u,...d])f.set(e.id,e);return{roles:s,directPermissions:u,effectivePermissions:Array.from(f.values())}}export{v as assignPermissionToRole,S as assignPermissionToUser,b as assignRoleToUser,h as createPermission,f as createRole,g as deletePermission,p as deleteRole,m as getPermissions,d as getRoleById,_ as getRolePermissions,u as getRoles,w as getUserRbacData,y as revokePermissionFromRole,C as revokePermissionFromUser,x as revokeRoleFromUser};
2
+ //# sourceMappingURL=rbac.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rbac.mjs","names":[],"sources":["../../../src/core/auth/rbac.ts"],"sourcesContent":["\"use server\";\n\nimport { and, eq, inArray } from \"drizzle-orm\";\nimport { db } from \"../../server/database/inject\";\nimport {\n permissionsTable,\n rolesTable,\n rolesToPermissionsTable,\n usersToPermissionsTable,\n usersToRolesTable,\n} from \"../../server/database/schema\";\nimport { notificationService } from \"../notifications/index\";\n\n// Ensure notification service is loaded\nif (typeof window === \"undefined\") {\n notificationService.init();\n}\n\n/**\n * CORE RBAC LOGIC\n * This file handles all database operations for Roles and Permissions.\n */\n\n// --- Roles ---\n\nexport async function getRoles() {\n return await db.select().from(rolesTable).orderBy(rolesTable.name);\n}\n\nexport async function getRoleById(roleId: string) {\n const [role] = await db\n .select()\n .from(rolesTable)\n .where(eq(rolesTable.id, roleId));\n return role;\n}\n\nexport async function createRole(name: string, description?: string) {\n return await db.insert(rolesTable).values({ name, description }).returning();\n}\n\nexport async function deleteRole(roleId: string) {\n return await db.delete(rolesTable).where(eq(rolesTable.id, roleId));\n}\n\n// --- Permissions ---\n\nexport async function getPermissions() {\n return await db\n .select()\n .from(permissionsTable)\n .orderBy(permissionsTable.name);\n}\n\nexport async function createPermission(name: string, description?: string) {\n return await db\n .insert(permissionsTable)\n .values({ name, description })\n .returning();\n}\n\nexport async function deletePermission(permissionId: string) {\n return await db\n .delete(permissionsTable)\n .where(eq(permissionsTable.id, permissionId));\n}\n\n// --- Mappings ---\n\nexport async function getRolePermissions(roleId: string) {\n return await db\n .select({\n id: permissionsTable.id,\n name: permissionsTable.name,\n })\n .from(rolesToPermissionsTable)\n .innerJoin(\n permissionsTable,\n eq(rolesToPermissionsTable.permissionId, permissionsTable.id),\n )\n .where(eq(rolesToPermissionsTable.roleId, roleId));\n}\n\nexport async function assignPermissionToRole(\n roleId: string,\n permissionId: string,\n) {\n return await db\n .insert(rolesToPermissionsTable)\n .values({ roleId, permissionId })\n .onConflictDoNothing();\n}\n\nexport async function revokePermissionFromRole(\n roleId: string,\n permissionId: string,\n) {\n return await db\n .delete(rolesToPermissionsTable)\n .where(\n and(\n eq(rolesToPermissionsTable.roleId, roleId),\n eq(rolesToPermissionsTable.permissionId, permissionId),\n ),\n );\n}\n\n// --- User Assignment ---\n\nexport async function assignRoleToUser(userId: string, roleId: string) {\n return await db\n .insert(usersToRolesTable)\n .values({ userId, roleId })\n .onConflictDoNothing();\n}\n\nexport async function revokeRoleFromUser(userId: string, roleId: string) {\n return await db\n .delete(usersToRolesTable)\n .where(\n and(\n eq(usersToRolesTable.userId, userId),\n eq(usersToRolesTable.roleId, roleId),\n ),\n );\n}\n\nexport async function assignPermissionToUser(\n userId: string,\n permissionId: string,\n) {\n return await db\n .insert(usersToPermissionsTable)\n .values({ userId, permissionId })\n .onConflictDoNothing();\n}\n\nexport async function revokePermissionFromUser(\n userId: string,\n permissionId: string,\n) {\n return await db\n .delete(usersToPermissionsTable)\n .where(\n and(\n eq(usersToPermissionsTable.userId, userId),\n eq(usersToPermissionsTable.permissionId, permissionId),\n ),\n );\n}\n\nexport async function getUserRbacData(userId: string) {\n const roles = await db\n .select({\n id: rolesTable.id,\n name: rolesTable.name,\n })\n .from(usersToRolesTable)\n .innerJoin(rolesTable, eq(usersToRolesTable.roleId, rolesTable.id))\n .where(eq(usersToRolesTable.userId, userId));\n\n const directPermissions = await db\n .select({\n id: permissionsTable.id,\n name: permissionsTable.name,\n })\n .from(usersToPermissionsTable)\n .innerJoin(\n permissionsTable,\n eq(usersToPermissionsTable.permissionId, permissionsTable.id),\n )\n .where(eq(usersToPermissionsTable.userId, userId));\n\n // Fetch inherited permissions from roles\n let rolePermissions: { id: string; name: string }[] = [];\n if (roles.length > 0) {\n const roleIds = roles.map((r) => r.id);\n rolePermissions = await db\n .select({\n id: permissionsTable.id,\n name: permissionsTable.name,\n })\n .from(rolesToPermissionsTable)\n .innerJoin(\n permissionsTable,\n eq(rolesToPermissionsTable.permissionId, permissionsTable.id),\n )\n .where(inArray(rolesToPermissionsTable.roleId, roleIds));\n }\n\n // Combine for effective permissions\n const effectiveMap = new Map<string, { id: string; name: string }>();\n for (const p of [...directPermissions, ...rolePermissions]) {\n effectiveMap.set(p.id, p);\n }\n\n return {\n roles,\n directPermissions,\n effectivePermissions: Array.from(effectiveMap.values()),\n };\n}\n"],"mappings":"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"}
@@ -0,0 +1 @@
1
+ "use server";require(`../../_virtual/_rolldown/runtime.cjs`);const e=require(`../../server/database/inject.cjs`),t=require(`../../server/database/schema.cjs`),n=require(`./augment.cjs`),r=require(`./logic.cjs`);let i=require(`drizzle-orm`),a=require(`@oslojs/crypto/sha2`),o=require(`@oslojs/encoding`),s=require(`date-fns`),c=require(`next/headers`),l=require(`next/navigation`);async function u(){return(await(0,c.headers)()).get(`x-forwarded-for`)}async function d(s){let c=(0,o.encodeHexLowerCase)((0,a.sha256)(new TextEncoder().encode(s))),[l]=await e.db.select({session:t.sessionTable,user:t.userTable}).from(t.sessionTable).innerJoin(t.userTable,(0,i.eq)(t.sessionTable.userId,t.userTable.id)).where((0,i.eq)(t.sessionTable.id,c));if(!l||!l.user)return{session:null,user:null};let{session:u,user:d}=l,{password:f,recovery_code:p,...m}=d;if(new Date>u.expiresAt)return await e.db.delete(t.sessionTable).where((0,i.eq)(t.sessionTable.id,u.id)),{session:null,user:null};let h=await r.performFullUserAugmentation(m),g=await n.augmentSession(u);return{session:g?{...g}:null,user:h?{...h}:null}}const f=async()=>{let e=(await(0,c.cookies)()).get(`session`)?.value??null;return e===null?{session:null,user:null}:await d(e)};async function p(n){await e.db.delete(t.sessionTable).where((0,i.eq)(t.sessionTable.id,n))}async function m(n){await e.db.delete(t.sessionTable).where((0,i.eq)(t.sessionTable.userId,n))}async function h(e,t){(await(0,c.cookies)()).set(`session`,e,{httpOnly:!0,path:`/`,secure:process.env.NODE_ENV===`production`,sameSite:`lax`,expires:t})}async function g(){(await(0,c.cookies)()).delete(`session`)}async function _(){let e=new Uint8Array(20);return crypto.getRandomValues(e),(0,o.encodeBase32LowerCaseNoPadding)(e).toLowerCase()}async function v(n,r,i){let c=(0,o.encodeHexLowerCase)((0,a.sha256)(new TextEncoder().encode(n))),[l]=await e.db.insert(t.sessionTable).values({id:c,expiresAt:new Date((0,s.addDays)(new Date,7)),active_organization_id:i.activeOrganizationId,userId:r}).returning();return l}async function y(){let{session:e}=await f();e&&(await p(e.id),await g()),(0,l.redirect)(`/signin`)}async function b(n,r){return(await e.db.select().from(t.sessionTable).where((0,i.eq)(t.sessionTable.userId,n))).map(e=>({id:e.id,createdAt:e.createdAt,expiresAt:e.expiresAt,isCurrent:e.id===r}))}async function x(n,r){await e.db.delete(t.sessionTable).where((0,i.and)((0,i.eq)(t.sessionTable.userId,n),(0,i.ne)(t.sessionTable.id,r)))}exports.createSession=v,exports.deleteSessionTokenCookie=g,exports.generateSessionToken=_,exports.getCurrentSession=f,exports.getIPAddress=u,exports.getUserSessions=b,exports.invalidateOtherSessions=x,exports.invalidateSession=p,exports.invalidateUserSessions=m,exports.sessionSignOut=y,exports.setSessionTokenCookie=h,exports.validateSessionToken=d;
@@ -0,0 +1,54 @@
1
+ import { AuthSession, Session, SessionFlags, UserSession } from "./types.cjs";
2
+
3
+ //#region src/core/auth/session.d.ts
4
+ /**
5
+ * Returns the user's IP address.
6
+ */
7
+ declare function getIPAddress(): Promise<string | null>;
8
+ /**
9
+ * Validates the session token.
10
+ */
11
+ declare function validateSessionToken(token: string): Promise<AuthSession>;
12
+ /**
13
+ * Returns the current user session from cookies.
14
+ */
15
+ declare const getCurrentSession: () => Promise<AuthSession>;
16
+ /**
17
+ * Invalidates a single session.
18
+ */
19
+ declare function invalidateSession(sessionId: string): Promise<void>;
20
+ /**
21
+ * Invalidates all user sessions.
22
+ */
23
+ declare function invalidateUserSessions(userId: string): Promise<void>;
24
+ /**
25
+ * Sets the session token in a cookie.
26
+ */
27
+ declare function setSessionTokenCookie(token: string, expiresAt: Date): Promise<void>;
28
+ /**
29
+ * Removes the session token cookie.
30
+ */
31
+ declare function deleteSessionTokenCookie(): Promise<void>;
32
+ /**
33
+ * Generates a new random session token.
34
+ */
35
+ declare function generateSessionToken(): Promise<string>;
36
+ /**
37
+ * Creates a new session in the database.
38
+ */
39
+ declare function createSession(token: string, userId: string, flags: SessionFlags): Promise<Session>;
40
+ /**
41
+ * Signs the user out and redirects to the sign-in page.
42
+ */
43
+ declare function sessionSignOut(): Promise<void>;
44
+ /**
45
+ * Get all active sessions for a user.
46
+ */
47
+ declare function getUserSessions(userId: string, currentSessionId: string): Promise<UserSession[]>;
48
+ /**
49
+ * Invalidate all sessions for a user except the specified current one.
50
+ */
51
+ declare function invalidateOtherSessions(userId: string, currentSessionId: string): Promise<void>;
52
+ //#endregion
53
+ export { createSession, deleteSessionTokenCookie, generateSessionToken, getCurrentSession, getIPAddress, getUserSessions, invalidateOtherSessions, invalidateSession, invalidateUserSessions, sessionSignOut, setSessionTokenCookie, validateSessionToken };
54
+ //# sourceMappingURL=session.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.d.cts","names":[],"sources":["../../../src/core/auth/session.ts"],"mappings":";;;;;AA2BA;iBAAsB,YAAA,CAAA,GAAgB,OAAA;;;;iBAOhB,oBAAA,CACpB,KAAA,WACC,OAAA,CAAQ,WAAA;;;;cAyCE,iBAAA,QAA8B,OAAA,CAAQ,WAAA;;;;iBAc7B,iBAAA,CAAkB,SAAA,WAAoB,OAAA;AAd5D;;;AAAA,iBAqBsB,sBAAA,CAAuB,MAAA,WAAiB,OAAA;;AAP9D;;iBAcsB,qBAAA,CACpB,KAAA,UACA,SAAA,EAAW,IAAA,GACV,OAAA;;;AAVH;iBAwBsB,wBAAA,CAAA,GAA4B,OAAA;;;;iBAQ5B,oBAAA,CAAA,GAAwB,OAAA;;;;iBASxB,aAAA,CACpB,KAAA,UACA,MAAA,UACA,KAAA,EAAO,YAAA,GACN,OAAA,CAAQ,OAAA;;;;iBAmBW,cAAA,CAAA,GAAc,OAAA;;AAxCpC;;iBAsDsB,eAAA,CACpB,MAAA,UACA,gBAAA,WACC,OAAA,CAAQ,WAAA;;;AAjDX;iBAkEsB,uBAAA,CACpB,MAAA,UACA,gBAAA,WACC,OAAA"}
@@ -0,0 +1,54 @@
1
+ import { AuthSession, Session, SessionFlags, UserSession } from "./types.mjs";
2
+
3
+ //#region src/core/auth/session.d.ts
4
+ /**
5
+ * Returns the user's IP address.
6
+ */
7
+ declare function getIPAddress(): Promise<string | null>;
8
+ /**
9
+ * Validates the session token.
10
+ */
11
+ declare function validateSessionToken(token: string): Promise<AuthSession>;
12
+ /**
13
+ * Returns the current user session from cookies.
14
+ */
15
+ declare const getCurrentSession: () => Promise<AuthSession>;
16
+ /**
17
+ * Invalidates a single session.
18
+ */
19
+ declare function invalidateSession(sessionId: string): Promise<void>;
20
+ /**
21
+ * Invalidates all user sessions.
22
+ */
23
+ declare function invalidateUserSessions(userId: string): Promise<void>;
24
+ /**
25
+ * Sets the session token in a cookie.
26
+ */
27
+ declare function setSessionTokenCookie(token: string, expiresAt: Date): Promise<void>;
28
+ /**
29
+ * Removes the session token cookie.
30
+ */
31
+ declare function deleteSessionTokenCookie(): Promise<void>;
32
+ /**
33
+ * Generates a new random session token.
34
+ */
35
+ declare function generateSessionToken(): Promise<string>;
36
+ /**
37
+ * Creates a new session in the database.
38
+ */
39
+ declare function createSession(token: string, userId: string, flags: SessionFlags): Promise<Session>;
40
+ /**
41
+ * Signs the user out and redirects to the sign-in page.
42
+ */
43
+ declare function sessionSignOut(): Promise<void>;
44
+ /**
45
+ * Get all active sessions for a user.
46
+ */
47
+ declare function getUserSessions(userId: string, currentSessionId: string): Promise<UserSession[]>;
48
+ /**
49
+ * Invalidate all sessions for a user except the specified current one.
50
+ */
51
+ declare function invalidateOtherSessions(userId: string, currentSessionId: string): Promise<void>;
52
+ //#endregion
53
+ export { createSession, deleteSessionTokenCookie, generateSessionToken, getCurrentSession, getIPAddress, getUserSessions, invalidateOtherSessions, invalidateSession, invalidateUserSessions, sessionSignOut, setSessionTokenCookie, validateSessionToken };
54
+ //# sourceMappingURL=session.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.d.mts","names":[],"sources":["../../../src/core/auth/session.ts"],"mappings":";;;;;AA2BA;iBAAsB,YAAA,CAAA,GAAgB,OAAA;;;;iBAOhB,oBAAA,CACpB,KAAA,WACC,OAAA,CAAQ,WAAA;;;;cAyCE,iBAAA,QAA8B,OAAA,CAAQ,WAAA;;;;iBAc7B,iBAAA,CAAkB,SAAA,WAAoB,OAAA;AAd5D;;;AAAA,iBAqBsB,sBAAA,CAAuB,MAAA,WAAiB,OAAA;;AAP9D;;iBAcsB,qBAAA,CACpB,KAAA,UACA,SAAA,EAAW,IAAA,GACV,OAAA;;;AAVH;iBAwBsB,wBAAA,CAAA,GAA4B,OAAA;;;;iBAQ5B,oBAAA,CAAA,GAAwB,OAAA;;;;iBASxB,aAAA,CACpB,KAAA,UACA,MAAA,UACA,KAAA,EAAO,YAAA,GACN,OAAA,CAAQ,OAAA;;;;iBAmBW,cAAA,CAAA,GAAc,OAAA;;AAxCpC;;iBAsDsB,eAAA,CACpB,MAAA,UACA,gBAAA,WACC,OAAA,CAAQ,WAAA;;;AAjDX;iBAkEsB,uBAAA,CACpB,MAAA,UACA,gBAAA,WACC,OAAA"}
@@ -0,0 +1,2 @@
1
+ "use server";import{db as e}from"../../server/database/inject.mjs";import{sessionTable as t,userTable as n}from"../../server/database/schema.mjs";import{augmentSession as r}from"./augment.mjs";import{performFullUserAugmentation as i}from"./logic.mjs";import{and as a,eq as o,ne as s}from"drizzle-orm";import{sha256 as c}from"@oslojs/crypto/sha2";import{encodeBase32LowerCaseNoPadding as l,encodeHexLowerCase as u}from"@oslojs/encoding";import{addDays as d}from"date-fns";import{cookies as f,headers as p}from"next/headers";import{redirect as m}from"next/navigation";async function h(){return(await p()).get(`x-forwarded-for`)}async function g(a){let s=u(c(new TextEncoder().encode(a))),[l]=await e.select({session:t,user:n}).from(t).innerJoin(n,o(t.userId,n.id)).where(o(t.id,s));if(!l||!l.user)return{session:null,user:null};let{session:d,user:f}=l,{password:p,recovery_code:m,...h}=f;if(new Date>d.expiresAt)return await e.delete(t).where(o(t.id,d.id)),{session:null,user:null};let g=await i(h),_=await r(d);return{session:_?{..._}:null,user:g?{...g}:null}}const _=async()=>{let e=(await f()).get(`session`)?.value??null;return e===null?{session:null,user:null}:await g(e)};async function v(n){await e.delete(t).where(o(t.id,n))}async function y(n){await e.delete(t).where(o(t.userId,n))}async function b(e,t){(await f()).set(`session`,e,{httpOnly:!0,path:`/`,secure:process.env.NODE_ENV===`production`,sameSite:`lax`,expires:t})}async function x(){(await f()).delete(`session`)}async function S(){let e=new Uint8Array(20);return crypto.getRandomValues(e),l(e).toLowerCase()}async function C(n,r,i){let a=u(c(new TextEncoder().encode(n))),[o]=await e.insert(t).values({id:a,expiresAt:new Date(d(new Date,7)),active_organization_id:i.activeOrganizationId,userId:r}).returning();return o}async function w(){let{session:e}=await _();e&&(await v(e.id),await x()),m(`/signin`)}async function T(n,r){return(await e.select().from(t).where(o(t.userId,n))).map(e=>({id:e.id,createdAt:e.createdAt,expiresAt:e.expiresAt,isCurrent:e.id===r}))}async function E(n,r){await e.delete(t).where(a(o(t.userId,n),s(t.id,r)))}export{C as createSession,x as deleteSessionTokenCookie,S as generateSessionToken,_ as getCurrentSession,h as getIPAddress,T as getUserSessions,E as invalidateOtherSessions,v as invalidateSession,y as invalidateUserSessions,w as sessionSignOut,b as setSessionTokenCookie,g as validateSessionToken};
2
+ //# sourceMappingURL=session.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.mjs","names":[],"sources":["../../../src/core/auth/session.ts"],"sourcesContent":["\"use server\";\n\nimport { sha256 } from \"@oslojs/crypto/sha2\";\nimport {\n encodeBase32LowerCaseNoPadding,\n encodeHexLowerCase,\n} from \"@oslojs/encoding\";\nimport { addDays } from \"date-fns\";\nimport { and, eq, ne } from \"drizzle-orm\";\nimport { cookies, headers } from \"next/headers\";\nimport { redirect } from \"next/navigation\";\nimport { db } from \"../../server/database/inject\";\nimport { sessionTable, userTable } from \"../../server/database/schema\";\nimport { augmentSession } from \"./augment\";\nimport { performFullUserAugmentation } from \"./logic\";\n\nimport type {\n AuthSession,\n Session,\n SessionFlags,\n User,\n UserSession,\n} from \"./types\";\n\n/**\n * Returns the user's IP address.\n */\nexport async function getIPAddress(): Promise<string | null> {\n return (await headers()).get(\"x-forwarded-for\");\n}\n\n/**\n * Validates the session token.\n */\nexport async function validateSessionToken(\n token: string,\n): Promise<AuthSession> {\n const sessionId = encodeHexLowerCase(sha256(new TextEncoder().encode(token)));\n\n const [row] = await db\n .select({\n session: sessionTable,\n user: userTable,\n })\n .from(sessionTable)\n .innerJoin(userTable, eq(sessionTable.userId, userTable.id))\n .where(eq(sessionTable.id, sessionId));\n\n if (!row || !row.user) {\n return { session: null, user: null };\n }\n\n const { session: baseSession, user: baseUser } = row;\n\n // STRICTLY remove non-serializable and sensitive fields\n const { password, recovery_code, ...safeUser } = baseUser;\n\n // Check if session is expired\n if (new Date() > baseSession.expiresAt) {\n await db.delete(sessionTable).where(eq(sessionTable.id, baseSession.id));\n return { session: null, user: null };\n }\n\n // AUGMENT (EXTENSIBILITY POINTS)\n const augmentedUser = await performFullUserAugmentation(safeUser as User);\n const augmentedSession = await augmentSession(baseSession as Session);\n\n // ENSURE PLAIN OBJECTS for Client Components\n return {\n session: augmentedSession ? { ...augmentedSession } : null,\n user: augmentedUser ? { ...augmentedUser } : null,\n };\n}\n\n/**\n * Returns the current user session from cookies.\n */\nexport const getCurrentSession = async (): Promise<AuthSession> => {\n const cookieStore = await cookies();\n const token = cookieStore.get(\"session\")?.value ?? null;\n\n if (token === null) {\n return { session: null, user: null };\n }\n\n return await validateSessionToken(token);\n};\n\n/**\n * Invalidates a single session.\n */\nexport async function invalidateSession(sessionId: string): Promise<void> {\n await db.delete(sessionTable).where(eq(sessionTable.id, sessionId));\n}\n\n/**\n * Invalidates all user sessions.\n */\nexport async function invalidateUserSessions(userId: string): Promise<void> {\n await db.delete(sessionTable).where(eq(sessionTable.userId, userId));\n}\n\n/**\n * Sets the session token in a cookie.\n */\nexport async function setSessionTokenCookie(\n token: string,\n expiresAt: Date,\n): Promise<void> {\n const cookieStore = await cookies();\n cookieStore.set(\"session\", token, {\n httpOnly: true,\n path: \"/\",\n secure: process.env.NODE_ENV === \"production\",\n sameSite: \"lax\",\n expires: expiresAt,\n });\n}\n\n/**\n * Removes the session token cookie.\n */\nexport async function deleteSessionTokenCookie(): Promise<void> {\n const cookieStore = await cookies();\n cookieStore.delete(\"session\");\n}\n\n/**\n * Generates a new random session token.\n */\nexport async function generateSessionToken(): Promise<string> {\n const tokenBytes = new Uint8Array(20);\n crypto.getRandomValues(tokenBytes);\n return encodeBase32LowerCaseNoPadding(tokenBytes).toLowerCase();\n}\n\n/**\n * Creates a new session in the database.\n */\nexport async function createSession(\n token: string,\n userId: string,\n flags: SessionFlags,\n): Promise<Session> {\n const sessionId = encodeHexLowerCase(sha256(new TextEncoder().encode(token)));\n\n const [session] = await db\n .insert(sessionTable)\n .values({\n id: sessionId,\n expiresAt: new Date(addDays(new Date(), 7)),\n active_organization_id: flags.activeOrganizationId,\n userId: userId,\n })\n .returning();\n\n return session;\n}\n\n/**\n * Signs the user out and redirects to the sign-in page.\n */\nexport async function sessionSignOut() {\n const { session } = await getCurrentSession();\n\n if (session) {\n await invalidateSession(session.id);\n await deleteSessionTokenCookie();\n }\n\n redirect(\"/signin\");\n}\n\n/**\n * Get all active sessions for a user.\n */\nexport async function getUserSessions(\n userId: string,\n currentSessionId: string,\n): Promise<UserSession[]> {\n const sessions = await db\n .select()\n .from(sessionTable)\n .where(eq(sessionTable.userId, userId));\n\n return sessions.map((session) => ({\n id: session.id,\n createdAt: session.createdAt,\n expiresAt: session.expiresAt,\n isCurrent: session.id === currentSessionId,\n }));\n}\n\n/**\n * Invalidate all sessions for a user except the specified current one.\n */\nexport async function invalidateOtherSessions(\n userId: string,\n currentSessionId: string,\n): Promise<void> {\n await db\n .delete(sessionTable)\n .where(\n and(\n eq(sessionTable.userId, userId),\n ne(sessionTable.id, currentSessionId),\n ),\n );\n}\n"],"mappings":"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"}
@@ -0,0 +1,55 @@
1
+ import { passwordResetSessionTable, sessionTable, userTable } from "../../server/database/schema.cjs";
2
+ import { UserPermission, UserRole } from "../types.cjs";
3
+
4
+ //#region src/core/auth/types.d.ts
5
+ type User = typeof userTable.$inferSelect;
6
+ type Session = typeof sessionTable.$inferSelect & Record<string, any>;
7
+ type PasswordResetSession = typeof passwordResetSessionTable.$inferSelect & Record<string, any>;
8
+ /**
9
+ * Represents a user with all potential extensions.
10
+ * Use this type in UI components that require data added by modules.
11
+ */
12
+ type FullUser = User & Record<string, any> & {
13
+ roles: UserRole[];
14
+ permissions: UserPermission[];
15
+ };
16
+ /**
17
+ * Basic session context.
18
+ */
19
+ interface AuthSession {
20
+ session: Session | null;
21
+ user: FullUser | null;
22
+ }
23
+ interface SessionFlags {
24
+ [key: string]: any;
25
+ }
26
+ type UserSession = {
27
+ id: string;
28
+ createdAt: Date;
29
+ expiresAt: Date;
30
+ isCurrent: boolean;
31
+ [key: string]: any;
32
+ };
33
+ type AuthResponse = {
34
+ status: "SUCCESS";
35
+ session: Session;
36
+ user: FullUser;
37
+ redirect?: string;
38
+ } | {
39
+ status: "CHALLENGE_REQUIRED";
40
+ type: string;
41
+ userId: string;
42
+ tempToken?: string;
43
+ redirect?: string;
44
+ } | {
45
+ status: "ERROR";
46
+ message: string;
47
+ redirect?: string;
48
+ };
49
+ interface PasswordResetAuthSession {
50
+ session: PasswordResetSession | null;
51
+ user: FullUser | null;
52
+ }
53
+ //#endregion
54
+ export { AuthResponse, AuthSession, FullUser, PasswordResetAuthSession, PasswordResetSession, Session, SessionFlags, User, UserSession };
55
+ //# sourceMappingURL=types.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.cts","names":[],"sources":["../../../src/core/auth/types.ts"],"mappings":";;;;KASY,IAAA,UAAc,SAAA,CAAU,YAAA;AAAA,KACxB,OAAA,UAAiB,YAAA,CAAa,YAAA,GAAe,MAAA;AAAA,KAC7C,oBAAA,UACH,yBAAA,CAA0B,YAAA,GAAe,MAAA;;;;AAFlD;KAQY,QAAA,GAAW,IAAA,GACrB,MAAA;EACE,KAAA,EAAO,QAAA;EACP,WAAA,EAAa,cAAA;AAAA;;;;UAMA,WAAA;EACf,OAAA,EAAS,OAAA;EACT,IAAA,EAAM,QAAA;AAAA;AAAA,UAGS,YAAA;EAAA,CACd,GAAA;AAAA;AAAA,KAGS,WAAA;EACV,EAAA;EACA,SAAA,EAAW,IAAA;EACX,SAAA,EAAW,IAAA;EACX,SAAA;EAAA,CACC,GAAA;AAAA;AAAA,KAGS,YAAA;EACN,MAAA;EAAmB,OAAA,EAAS,OAAA;EAAS,IAAA,EAAM,QAAA;EAAU,QAAA;AAAA;EAEvD,MAAA;EACA,IAAA;EACA,MAAA;EACA,SAAA;EACA,QAAA;AAAA;EAEE,MAAA;EAAiB,OAAA;EAAiB,QAAA;AAAA;AAAA,UAEvB,wBAAA;EACf,OAAA,EAAS,oBAAA;EACT,IAAA,EAAM,QAAA;AAAA"}
@@ -0,0 +1,55 @@
1
+ import { passwordResetSessionTable, sessionTable, userTable } from "../../server/database/schema.mjs";
2
+ import { UserPermission, UserRole } from "../types.mjs";
3
+
4
+ //#region src/core/auth/types.d.ts
5
+ type User = typeof userTable.$inferSelect;
6
+ type Session = typeof sessionTable.$inferSelect & Record<string, any>;
7
+ type PasswordResetSession = typeof passwordResetSessionTable.$inferSelect & Record<string, any>;
8
+ /**
9
+ * Represents a user with all potential extensions.
10
+ * Use this type in UI components that require data added by modules.
11
+ */
12
+ type FullUser = User & Record<string, any> & {
13
+ roles: UserRole[];
14
+ permissions: UserPermission[];
15
+ };
16
+ /**
17
+ * Basic session context.
18
+ */
19
+ interface AuthSession {
20
+ session: Session | null;
21
+ user: FullUser | null;
22
+ }
23
+ interface SessionFlags {
24
+ [key: string]: any;
25
+ }
26
+ type UserSession = {
27
+ id: string;
28
+ createdAt: Date;
29
+ expiresAt: Date;
30
+ isCurrent: boolean;
31
+ [key: string]: any;
32
+ };
33
+ type AuthResponse = {
34
+ status: "SUCCESS";
35
+ session: Session;
36
+ user: FullUser;
37
+ redirect?: string;
38
+ } | {
39
+ status: "CHALLENGE_REQUIRED";
40
+ type: string;
41
+ userId: string;
42
+ tempToken?: string;
43
+ redirect?: string;
44
+ } | {
45
+ status: "ERROR";
46
+ message: string;
47
+ redirect?: string;
48
+ };
49
+ interface PasswordResetAuthSession {
50
+ session: PasswordResetSession | null;
51
+ user: FullUser | null;
52
+ }
53
+ //#endregion
54
+ export { AuthResponse, AuthSession, FullUser, PasswordResetAuthSession, PasswordResetSession, Session, SessionFlags, User, UserSession };
55
+ //# sourceMappingURL=types.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.mts","names":[],"sources":["../../../src/core/auth/types.ts"],"mappings":";;;;KASY,IAAA,UAAc,SAAA,CAAU,YAAA;AAAA,KACxB,OAAA,UAAiB,YAAA,CAAa,YAAA,GAAe,MAAA;AAAA,KAC7C,oBAAA,UACH,yBAAA,CAA0B,YAAA,GAAe,MAAA;;;;AAFlD;KAQY,QAAA,GAAW,IAAA,GACrB,MAAA;EACE,KAAA,EAAO,QAAA;EACP,WAAA,EAAa,cAAA;AAAA;;;;UAMA,WAAA;EACf,OAAA,EAAS,OAAA;EACT,IAAA,EAAM,QAAA;AAAA;AAAA,UAGS,YAAA;EAAA,CACd,GAAA;AAAA;AAAA,KAGS,WAAA;EACV,EAAA;EACA,SAAA,EAAW,IAAA;EACX,SAAA,EAAW,IAAA;EACX,SAAA;EAAA,CACC,GAAA;AAAA;AAAA,KAGS,YAAA;EACN,MAAA;EAAmB,OAAA,EAAS,OAAA;EAAS,IAAA,EAAM,QAAA;EAAU,QAAA;AAAA;EAEvD,MAAA;EACA,IAAA;EACA,MAAA;EACA,SAAA;EACA,QAAA;AAAA;EAEE,MAAA;EAAiB,OAAA;EAAiB,QAAA;AAAA;AAAA,UAEvB,wBAAA;EACf,OAAA,EAAS,oBAAA;EACT,IAAA,EAAM,QAAA;AAAA"}
@@ -0,0 +1 @@
1
+ require(`../../../_virtual/_rolldown/runtime.cjs`);let e=require(`@oslojs/encoding`);function t(t=6){let n=new Uint8Array(5);return crypto.getRandomValues(n),(0,e.encodeBase32UpperCaseNoPadding)(n).substring(0,t)}function n(){let t=new Uint8Array(10);return crypto.getRandomValues(t),(0,e.encodeBase32UpperCaseNoPadding)(t)}exports.generateRandomOTP=t,exports.generateRandomRecoveryCode=n;
@@ -0,0 +1,15 @@
1
+ //#region src/core/auth/utils/encode.d.ts
2
+ /**
3
+ * Generates a random one-time code (OTP).
4
+ * @param length Length of the generated code (default 6).
5
+ * @returns A random uppercase base32 string.
6
+ */
7
+ declare function generateRandomOTP(length?: number): string;
8
+ /**
9
+ * Generates a random recovery code.
10
+ * @returns A random uppercase base32 string.
11
+ */
12
+ declare function generateRandomRecoveryCode(): string;
13
+ //#endregion
14
+ export { generateRandomOTP, generateRandomRecoveryCode };
15
+ //# sourceMappingURL=encode.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"encode.d.cts","names":[],"sources":["../../../../src/core/auth/utils/encode.ts"],"mappings":";;AAOA;;;;iBAAgB,iBAAA,CAAkB,MAAA;AAUlC;;;;AAAA,iBAAgB,0BAAA,CAAA"}
@@ -0,0 +1,15 @@
1
+ //#region src/core/auth/utils/encode.d.ts
2
+ /**
3
+ * Generates a random one-time code (OTP).
4
+ * @param length Length of the generated code (default 6).
5
+ * @returns A random uppercase base32 string.
6
+ */
7
+ declare function generateRandomOTP(length?: number): string;
8
+ /**
9
+ * Generates a random recovery code.
10
+ * @returns A random uppercase base32 string.
11
+ */
12
+ declare function generateRandomRecoveryCode(): string;
13
+ //#endregion
14
+ export { generateRandomOTP, generateRandomRecoveryCode };
15
+ //# sourceMappingURL=encode.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"encode.d.mts","names":[],"sources":["../../../../src/core/auth/utils/encode.ts"],"mappings":";;AAOA;;;;iBAAgB,iBAAA,CAAkB,MAAA;AAUlC;;;;AAAA,iBAAgB,0BAAA,CAAA"}
@@ -0,0 +1,2 @@
1
+ import{encodeBase32UpperCaseNoPadding as e}from"@oslojs/encoding";function t(t=6){let n=new Uint8Array(5);return crypto.getRandomValues(n),e(n).substring(0,t)}function n(){let t=new Uint8Array(10);return crypto.getRandomValues(t),e(t)}export{t as generateRandomOTP,n as generateRandomRecoveryCode};
2
+ //# sourceMappingURL=encode.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"encode.mjs","names":[],"sources":["../../../../src/core/auth/utils/encode.ts"],"sourcesContent":["import { encodeBase32UpperCaseNoPadding } from \"@oslojs/encoding\";\n\n/**\n * Generates a random one-time code (OTP).\n * @param length Length of the generated code (default 6).\n * @returns A random uppercase base32 string.\n */\nexport function generateRandomOTP(length = 6): string {\n const bytes = new Uint8Array(5);\n crypto.getRandomValues(bytes);\n return encodeBase32UpperCaseNoPadding(bytes).substring(0, length);\n}\n\n/**\n * Generates a random recovery code.\n * @returns A random uppercase base32 string.\n */\nexport function generateRandomRecoveryCode(): string {\n const recoveryCodeBytes = new Uint8Array(10);\n crypto.getRandomValues(recoveryCodeBytes);\n return encodeBase32UpperCaseNoPadding(recoveryCodeBytes);\n}\n"],"mappings":"kEAOA,SAAgB,EAAkB,EAAS,EAAW,CACpD,IAAM,EAAQ,IAAI,WAAW,EAAE,CAE/B,OADA,OAAO,gBAAgB,EAAM,CACtB,EAA+B,EAAM,CAAC,UAAU,EAAG,EAAO,CAOnE,SAAgB,GAAqC,CACnD,IAAM,EAAoB,IAAI,WAAW,GAAG,CAE5C,OADA,OAAO,gBAAgB,EAAkB,CAClC,EAA+B,EAAkB"}
@@ -0,0 +1 @@
1
+ require(`../../../_virtual/_rolldown/runtime.cjs`);let e=require(`@oslojs/encoding`),t=require(`node:crypto`),n=require(`@oslojs/binary`);const r=process.env.ENCRYPTION_KEY;if(!r)throw Error(`ENCRYPTION_KEY environment variable is not set`);const i=(0,e.decodeBase64)(r);function a(e){let r=new Uint8Array(16);crypto.getRandomValues(r);let a=(0,t.createCipheriv)(`aes-128-gcm`,i,r),o=new n.DynamicBuffer(0);return o.write(r),o.write(a.update(e)),o.write(a.final()),o.write(a.getAuthTag()),o.bytes()}function o(e){return a(new TextEncoder().encode(e))}function s(e){if(e.byteLength<33)throw Error(`Invalid encrypted data length`);let r=e.slice(0,16),a=e.slice(e.byteLength-16),o=e.slice(16,e.byteLength-16),s=(0,t.createDecipheriv)(`aes-128-gcm`,i,r);s.setAuthTag(a);let c=new n.DynamicBuffer(0);return c.write(s.update(o)),c.write(s.final()),c.bytes()}function c(e){return new TextDecoder().decode(s(e))}exports.decrypt=s,exports.decryptToString=c,exports.encrypt=a,exports.encryptString=o;
@@ -1,25 +1,28 @@
1
+ //#region src/core/auth/utils/encryption.d.ts
1
2
  /**
2
3
  * Encrypts data using AES-128-GCM.
3
4
  * @param data Data to be encrypted.
4
5
  * @returns Encrypted data including IV and auth tag.
5
6
  */
6
- export declare function encrypt(data: Uint8Array): Uint8Array;
7
+ declare function encrypt(data: Uint8Array): Uint8Array;
7
8
  /**
8
9
  * Encrypts a string.
9
10
  * @param data String to be encrypted.
10
11
  * @returns Encrypted data as Uint8Array.
11
12
  */
12
- export declare function encryptString(data: string): Uint8Array;
13
+ declare function encryptString(data: string): Uint8Array;
13
14
  /**
14
15
  * Decrypts data using AES-128-GCM.
15
16
  * @param encrypted Encrypted data (IV + content + auth tag).
16
17
  * @returns Decrypted data.
17
18
  */
18
- export declare function decrypt(encrypted: Uint8Array): Uint8Array;
19
+ declare function decrypt(encrypted: Uint8Array): Uint8Array;
19
20
  /**
20
21
  * Decrypts data to a string.
21
22
  * @param data Encrypted data.
22
23
  * @returns Odszyfrowany ciąg znaków.
23
24
  */
24
- export declare function decryptToString(data: Uint8Array): string;
25
- //# sourceMappingURL=encryption.d.ts.map
25
+ declare function decryptToString(data: Uint8Array): string;
26
+ //#endregion
27
+ export { decrypt, decryptToString, encrypt, encryptString };
28
+ //# sourceMappingURL=encryption.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"encryption.d.cts","names":[],"sources":["../../../../src/core/auth/utils/encryption.ts"],"mappings":";;AAoBA;;;;iBAAgB,OAAA,CAAQ,IAAA,EAAM,UAAA,GAAa,UAAA;;;;;AAiB3C;iBAAgB,aAAA,CAAc,IAAA,WAAe,UAAA;;;;AAS7C;;iBAAgB,OAAA,CAAQ,SAAA,EAAW,UAAA,GAAa,UAAA;;;;;;iBAsBhC,eAAA,CAAgB,IAAA,EAAM,UAAA"}
@@ -0,0 +1,28 @@
1
+ //#region src/core/auth/utils/encryption.d.ts
2
+ /**
3
+ * Encrypts data using AES-128-GCM.
4
+ * @param data Data to be encrypted.
5
+ * @returns Encrypted data including IV and auth tag.
6
+ */
7
+ declare function encrypt(data: Uint8Array): Uint8Array;
8
+ /**
9
+ * Encrypts a string.
10
+ * @param data String to be encrypted.
11
+ * @returns Encrypted data as Uint8Array.
12
+ */
13
+ declare function encryptString(data: string): Uint8Array;
14
+ /**
15
+ * Decrypts data using AES-128-GCM.
16
+ * @param encrypted Encrypted data (IV + content + auth tag).
17
+ * @returns Decrypted data.
18
+ */
19
+ declare function decrypt(encrypted: Uint8Array): Uint8Array;
20
+ /**
21
+ * Decrypts data to a string.
22
+ * @param data Encrypted data.
23
+ * @returns Odszyfrowany ciąg znaków.
24
+ */
25
+ declare function decryptToString(data: Uint8Array): string;
26
+ //#endregion
27
+ export { decrypt, decryptToString, encrypt, encryptString };
28
+ //# sourceMappingURL=encryption.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"encryption.d.mts","names":[],"sources":["../../../../src/core/auth/utils/encryption.ts"],"mappings":";;AAoBA;;;;iBAAgB,OAAA,CAAQ,IAAA,EAAM,UAAA,GAAa,UAAA;;;;;AAiB3C;iBAAgB,aAAA,CAAc,IAAA,WAAe,UAAA;;;;AAS7C;;iBAAgB,OAAA,CAAQ,SAAA,EAAW,UAAA,GAAa,UAAA;;;;;;iBAsBhC,eAAA,CAAgB,IAAA,EAAM,UAAA"}
@@ -0,0 +1,2 @@
1
+ import{decodeBase64 as e}from"@oslojs/encoding";import{createCipheriv as t,createDecipheriv as n}from"node:crypto";import{DynamicBuffer as r}from"@oslojs/binary";const i=process.env.ENCRYPTION_KEY;if(!i)throw Error(`ENCRYPTION_KEY environment variable is not set`);const a=e(i);function o(e){let n=new Uint8Array(16);crypto.getRandomValues(n);let i=t(`aes-128-gcm`,a,n),o=new r(0);return o.write(n),o.write(i.update(e)),o.write(i.final()),o.write(i.getAuthTag()),o.bytes()}function s(e){return o(new TextEncoder().encode(e))}function c(e){if(e.byteLength<33)throw Error(`Invalid encrypted data length`);let t=e.slice(0,16),i=e.slice(e.byteLength-16),o=e.slice(16,e.byteLength-16),s=n(`aes-128-gcm`,a,t);s.setAuthTag(i);let c=new r(0);return c.write(s.update(o)),c.write(s.final()),c.bytes()}function l(e){return new TextDecoder().decode(c(e))}export{c as decrypt,l as decryptToString,o as encrypt,s as encryptString};
2
+ //# sourceMappingURL=encryption.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"encryption.mjs","names":[],"sources":["../../../../src/core/auth/utils/encryption.ts"],"sourcesContent":["import { createCipheriv, createDecipheriv } from \"node:crypto\";\nimport { DynamicBuffer } from \"@oslojs/binary\";\nimport { decodeBase64 } from \"@oslojs/encoding\";\n\nconst ENCRYPTION_KEY = process.env.ENCRYPTION_KEY;\n\nif (!ENCRYPTION_KEY) {\n throw new Error(\"ENCRYPTION_KEY environment variable is not set\");\n}\n\n/**\n * The encryption key decoded from base64.\n */\nconst key = decodeBase64(ENCRYPTION_KEY);\n\n/**\n * Encrypts data using AES-128-GCM.\n * @param data Data to be encrypted.\n * @returns Encrypted data including IV and auth tag.\n */\nexport function encrypt(data: Uint8Array): Uint8Array {\n const iv = new Uint8Array(16);\n crypto.getRandomValues(iv);\n const cipher = createCipheriv(\"aes-128-gcm\", key, iv);\n const encrypted = new DynamicBuffer(0);\n encrypted.write(iv);\n encrypted.write(cipher.update(data));\n encrypted.write(cipher.final());\n encrypted.write(cipher.getAuthTag());\n return encrypted.bytes();\n}\n\n/**\n * Encrypts a string.\n * @param data String to be encrypted.\n * @returns Encrypted data as Uint8Array.\n */\nexport function encryptString(data: string): Uint8Array {\n return encrypt(new TextEncoder().encode(data));\n}\n\n/**\n * Decrypts data using AES-128-GCM.\n * @param encrypted Encrypted data (IV + content + auth tag).\n * @returns Decrypted data.\n */\nexport function decrypt(encrypted: Uint8Array): Uint8Array {\n if (encrypted.byteLength < 33) {\n throw new Error(\"Invalid encrypted data length\");\n }\n const iv = encrypted.slice(0, 16);\n const authTag = encrypted.slice(encrypted.byteLength - 16);\n const content = encrypted.slice(16, encrypted.byteLength - 16);\n\n const decipher = createDecipheriv(\"aes-128-gcm\", key, iv);\n decipher.setAuthTag(authTag);\n\n const decrypted = new DynamicBuffer(0);\n decrypted.write(decipher.update(content));\n decrypted.write(decipher.final());\n return decrypted.bytes();\n}\n\n/**\n * Decrypts data to a string.\n * @param data Encrypted data.\n * @returns Odszyfrowany ciąg znaków.\n */\nexport function decryptToString(data: Uint8Array): string {\n return new TextDecoder().decode(decrypt(data));\n}\n"],"mappings":"kKAIA,MAAM,EAAiB,QAAQ,IAAI,eAEnC,GAAI,CAAC,EACH,MAAU,MAAM,iDAAiD,CAMnE,MAAM,EAAM,EAAa,EAAe,CAOxC,SAAgB,EAAQ,EAA8B,CACpD,IAAM,EAAK,IAAI,WAAW,GAAG,CAC7B,OAAO,gBAAgB,EAAG,CAC1B,IAAM,EAAS,EAAe,cAAe,EAAK,EAAG,CAC/C,EAAY,IAAI,EAAc,EAAE,CAKtC,OAJA,EAAU,MAAM,EAAG,CACnB,EAAU,MAAM,EAAO,OAAO,EAAK,CAAC,CACpC,EAAU,MAAM,EAAO,OAAO,CAAC,CAC/B,EAAU,MAAM,EAAO,YAAY,CAAC,CAC7B,EAAU,OAAO,CAQ1B,SAAgB,EAAc,EAA0B,CACtD,OAAO,EAAQ,IAAI,aAAa,CAAC,OAAO,EAAK,CAAC,CAQhD,SAAgB,EAAQ,EAAmC,CACzD,GAAI,EAAU,WAAa,GACzB,MAAU,MAAM,gCAAgC,CAElD,IAAM,EAAK,EAAU,MAAM,EAAG,GAAG,CAC3B,EAAU,EAAU,MAAM,EAAU,WAAa,GAAG,CACpD,EAAU,EAAU,MAAM,GAAI,EAAU,WAAa,GAAG,CAExD,EAAW,EAAiB,cAAe,EAAK,EAAG,CACzD,EAAS,WAAW,EAAQ,CAE5B,IAAM,EAAY,IAAI,EAAc,EAAE,CAGtC,OAFA,EAAU,MAAM,EAAS,OAAO,EAAQ,CAAC,CACzC,EAAU,MAAM,EAAS,OAAO,CAAC,CAC1B,EAAU,OAAO,CAQ1B,SAAgB,EAAgB,EAA0B,CACxD,OAAO,IAAI,aAAa,CAAC,OAAO,EAAQ,EAAK,CAAC"}
@@ -0,0 +1 @@
1
+ require(`../../_virtual/_rolldown/runtime.cjs`);let e=require(`zod`);const t=e.z.object({email:e.z.string().email(`Invalid email address`),password:e.z.string().min(8),remember:e.z.boolean().optional()}),n=e.z.object({username:e.z.string().min(2,`Name must be at least 2 characters`),email:e.z.string().email(`Invalid email address`),password:e.z.string().min(8,`Password must be at least 8 characters`),terms:e.z.boolean().refine(e=>e===!0,`You must accept the terms`)}),r=e.z.object({email:e.z.string().email(`Invalid email address`)}),i=e.z.object({password:e.z.string().min(8,`Password must be at least 8 characters`),confirm:e.z.string()}).refine(e=>e.password===e.confirm,{message:`Passwords do not match`,path:[`confirm`]}),a=e.z.object({code:e.z.string().min(6).max(6)}),o=e.z.object({code:e.z.string().regex(/^\d{6}$/,`Code must be 6 digits`)}),s=e.z.object({code:e.z.string().regex(/^\d{6}$/,`Code must be 6 digits`)}),c=e.z.object({name:e.z.string().min(1,`Passkey name is required`)}),l=e.z.object({code:e.z.string().min(16,`Recovery code is required`).max(16)});exports.forgotPasswordSchema=r,exports.loginSchema=t,exports.passkeysSetupSchema=c,exports.recoveryCodeVerifySchema=l,exports.registerSchema=n,exports.resetPasswordSchema=i,exports.totpSetupSchema=o,exports.totpVerifySchema=s,exports.verifyEmailSchema=a;