@stratal/framework 0.0.17 → 0.0.19

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 (52) hide show
  1. package/dist/access-control/index.d.mts +180 -0
  2. package/dist/access-control/index.d.mts.map +1 -0
  3. package/dist/access-control/index.mjs +71 -0
  4. package/dist/access-control/index.mjs.map +1 -0
  5. package/dist/access.service-BjYVtUJw.mjs +145 -0
  6. package/dist/access.service-BjYVtUJw.mjs.map +1 -0
  7. package/dist/auth/index.d.mts +134 -13
  8. package/dist/auth/index.d.mts.map +1 -1
  9. package/dist/auth/index.mjs +262 -75
  10. package/dist/auth/index.mjs.map +1 -1
  11. package/dist/{auth-context-BD2ApWg1.d.mts → auth-context-BXSkiJ56.d.mts} +14 -1
  12. package/dist/auth-context-BXSkiJ56.d.mts.map +1 -0
  13. package/dist/{auth-context-CV3Ko1ew.mjs → auth-context-BberoPal.mjs} +25 -4
  14. package/dist/auth-context-BberoPal.mjs.map +1 -0
  15. package/dist/context/index.d.mts +1 -1
  16. package/dist/context/index.mjs +2 -2
  17. package/dist/database/index.d.mts +3 -3
  18. package/dist/database/index.mjs +49 -43
  19. package/dist/database/index.mjs.map +1 -1
  20. package/dist/{decorate-RSane8dy.mjs → decorate-CdfCRvAc.mjs} +1 -1
  21. package/dist/{decorateMetadata-CETItPez.mjs → decorateMetadata-CqtSx3_1.mjs} +1 -1
  22. package/dist/decorateParam-Dc5DGEpb.mjs +18 -0
  23. package/dist/decorateParam-Dc5DGEpb.mjs.map +1 -0
  24. package/dist/{errors-C_KIIU1v.mjs → errors-B1vVXc1T.mjs} +1 -1
  25. package/dist/{errors-C_KIIU1v.mjs.map → errors-B1vVXc1T.mjs.map} +1 -1
  26. package/dist/factory/index.d.mts +1 -1
  27. package/dist/guards/index.d.mts +7 -6
  28. package/dist/guards/index.d.mts.map +1 -1
  29. package/dist/guards/index.mjs +39 -30
  30. package/dist/guards/index.mjs.map +1 -1
  31. package/dist/{index-eukGTmI8.d.mts → index-CpFBG0Ws.d.mts} +26 -45
  32. package/dist/index-CpFBG0Ws.d.mts.map +1 -0
  33. package/dist/index.d.mts +2 -2
  34. package/dist/insufficient-permissions.error-CRnOHYvq.mjs +23 -0
  35. package/dist/insufficient-permissions.error-CRnOHYvq.mjs.map +1 -0
  36. package/dist/types-BLyu9dAd.d.mts +11 -0
  37. package/dist/types-BLyu9dAd.d.mts.map +1 -0
  38. package/dist/types-BZlcRR2M.d.mts +92 -0
  39. package/dist/types-BZlcRR2M.d.mts.map +1 -0
  40. package/package.json +25 -25
  41. package/dist/auth-context-BD2ApWg1.d.mts.map +0 -1
  42. package/dist/auth-context-CV3Ko1ew.mjs.map +0 -1
  43. package/dist/decorateParam-CcTvpNsw.mjs +0 -8
  44. package/dist/index-eukGTmI8.d.mts.map +0 -1
  45. package/dist/rbac/index.d.mts +0 -206
  46. package/dist/rbac/index.d.mts.map +0 -1
  47. package/dist/rbac/index.mjs +0 -346
  48. package/dist/rbac/index.mjs.map +0 -1
  49. package/dist/tokens-Di1ofovy.mjs +0 -32
  50. package/dist/tokens-Di1ofovy.mjs.map +0 -1
  51. package/dist/types-Gjk0d2qB.d.mts +0 -47
  52. package/dist/types-Gjk0d2qB.d.mts.map +0 -1
@@ -1,12 +1,14 @@
1
- import "../errors-C_KIIU1v.mjs";
2
- import { t as __decorate } from "../decorate-RSane8dy.mjs";
3
- import { t as AuthContext } from "../auth-context-CV3Ko1ew.mjs";
4
- import { t as __decorateMetadata } from "../decorateMetadata-CETItPez.mjs";
5
- import { t as __decorateParam } from "../decorateParam-CcTvpNsw.mjs";
1
+ import { n as createStratalAcPlugin, t as AccessService } from "../access.service-BjYVtUJw.mjs";
2
+ import { n as AC_TOKENS, t as __decorateParam } from "../decorateParam-Dc5DGEpb.mjs";
3
+ import { t as __decorateMetadata } from "../decorateMetadata-CqtSx3_1.mjs";
4
+ import { t as __decorate } from "../decorate-CdfCRvAc.mjs";
5
+ import { t as AuthContext } from "../auth-context-BberoPal.mjs";
6
+ import { I18nModule } from "stratal/i18n";
6
7
  import { Module } from "stratal/module";
7
8
  import { DI_TOKENS, Transient } from "stratal/di";
8
- import { ApplicationError, ERROR_CODES, InternalError } from "stratal/errors";
9
- import { inject } from "tsyringe";
9
+ import { ApplicationError, ERROR_CODES } from "stratal/errors";
10
+ import { LOGGER_TOKENS } from "stratal/logger";
11
+ import { inject as inject$1 } from "tsyringe";
10
12
  import { betterAuth } from "better-auth";
11
13
  import { APIError } from "better-auth/api";
12
14
  //#region src/auth/auth.tokens.ts
@@ -15,174 +17,315 @@ const AUTH_SERVICE = Symbol.for("stratal:auth:service");
15
17
  /** Token for Better Auth options configuration */
16
18
  const AUTH_OPTIONS = Symbol.for("stratal:auth:options");
17
19
  //#endregion
20
+ //#region src/auth/i18n/en.ts
21
+ const authMessages = { en: { auth: {
22
+ errors: {
23
+ tokenRequired: "Verification token is required",
24
+ invalidToken: "Invalid or expired verification token",
25
+ verificationFailed: "Verification failed. Please try again.",
26
+ userNotFound: "User not found. Please check your credentials.",
27
+ invalidCredentials: "Invalid email or password",
28
+ invalidPassword: "Invalid password",
29
+ invalidEmail: "Invalid email address",
30
+ sessionExpired: "Your session has expired. Please sign in again.",
31
+ emailNotVerified: "Please verify your email address before signing in",
32
+ passwordTooShort: "Password must be at least {minLength} characters",
33
+ passwordTooLong: "Password must be at most {maxLength} characters",
34
+ accountAlreadyExists: "An account with this email already exists",
35
+ failedToCreateUser: "Failed to create user account. Please try again.",
36
+ failedToCreateSession: "Failed to create session. Please try again.",
37
+ failedToGetSession: "Failed to retrieve session. Please try again.",
38
+ failedToUpdateUser: "Failed to update user information. Please try again.",
39
+ failedToGetUserInfo: "Failed to retrieve user information. Please try again.",
40
+ socialAccountLinked: "This social account is already linked to another user",
41
+ providerNotFound: "Authentication provider not found",
42
+ userEmailNotFound: "User email address not found",
43
+ accountNotFound: "Account not found",
44
+ credentialAccountNotFound: "Credential account not found",
45
+ cannotUnlinkLastAccount: "Cannot unlink your last account",
46
+ userAlreadyHasPassword: "User already has a password set",
47
+ emailCannotBeUpdated: "Email address cannot be updated at this time",
48
+ tokenExpired: "The verification token has expired. Please request a new verification email.",
49
+ invalidCallbackUrl: "Invalid callback URL",
50
+ invalidOrigin: "Request origin is not allowed",
51
+ validationFailed: "Authentication validation failed",
52
+ emailAlreadyVerified: "Email address is already verified",
53
+ emailMismatch: "Email address does not match",
54
+ unknownError: "An authentication error occurred"
55
+ },
56
+ org: {
57
+ organizationNotFound: "Organization not found",
58
+ memberNotFound: "Member not found",
59
+ invitationNotFound: "Invitation not found",
60
+ permissionDenied: "You do not have permission to perform this action",
61
+ invitationRecipientMismatch: "You are not the recipient of this invitation",
62
+ conflict: "A resource with this identifier already exists",
63
+ limitReached: "The maximum limit has been reached",
64
+ membershipError: "This action cannot be performed due to membership constraints",
65
+ teamNotFound: "Team not found",
66
+ roleNotFound: "Role not found"
67
+ }
68
+ } } };
69
+ //#endregion
18
70
  //#region src/auth/middleware/auth-context.middleware.ts
19
71
  let AuthContextMiddleware = class AuthContextMiddleware {
20
72
  async handle(ctx, next) {
21
73
  const requestContainer = ctx.getContainer();
22
74
  const authContext = new AuthContext();
23
75
  requestContainer.registerValue(DI_TOKENS.AuthContext, authContext);
24
- await next();
76
+ return next();
25
77
  }
26
78
  };
27
79
  AuthContextMiddleware = __decorate([Transient()], AuthContextMiddleware);
28
80
  //#endregion
29
81
  //#region src/auth/middleware/session-verification.middleware.ts
30
82
  let SessionVerificationMiddleware = class SessionVerificationMiddleware {
31
- constructor(authService) {
83
+ constructor(authService, logger) {
32
84
  this.authService = authService;
85
+ this.logger = logger;
33
86
  }
34
87
  async handle(ctx, next) {
35
- const session = await this.authService.auth.api.getSession({ headers: ctx.c.req.raw.headers });
36
- if (session) ctx.getContainer().resolve(DI_TOKENS.AuthContext).setAuthContext({ userId: session.user.id });
37
- await next();
88
+ try {
89
+ const session = await this.authService.auth.api.getSession({ headers: ctx.c.req.raw.headers });
90
+ if (session) ctx.getContainer().resolve(DI_TOKENS.AuthContext).setAuthContext({
91
+ userId: session.user.id,
92
+ role: session.user.role
93
+ });
94
+ } catch (error) {
95
+ this.logger.debug("Session validation failed (e.g., invalidated in DB)", { error });
96
+ }
97
+ return next();
38
98
  }
39
99
  };
40
100
  SessionVerificationMiddleware = __decorate([
41
101
  Transient(),
42
- __decorateParam(0, inject(AUTH_SERVICE)),
43
- __decorateMetadata("design:paramtypes", [Object])
102
+ __decorateParam(0, inject$1(AUTH_SERVICE)),
103
+ __decorateParam(1, inject$1(LOGGER_TOKENS.LoggerService)),
104
+ __decorateMetadata("design:paramtypes", [Object, Object])
44
105
  ], SessionVerificationMiddleware);
45
106
  //#endregion
46
107
  //#region src/auth/errors/auth-errors.ts
47
108
  var UserNotFoundError = class extends ApplicationError {
48
109
  constructor(email) {
49
- super("errors.auth.userNotFound", ERROR_CODES.RESOURCE.NOT_FOUND, email ? { email } : void 0);
110
+ super("auth.errors.userNotFound", ERROR_CODES.RESOURCE.NOT_FOUND, email ? { email } : void 0);
50
111
  }
51
112
  };
52
113
  var InvalidCredentialsError = class extends ApplicationError {
53
114
  constructor() {
54
- super("errors.auth.invalidCredentials", ERROR_CODES.AUTH.INVALID_CREDENTIALS);
115
+ super("auth.errors.invalidCredentials", ERROR_CODES.AUTH.INVALID_CREDENTIALS);
55
116
  }
56
117
  };
57
118
  var InvalidPasswordError = class extends ApplicationError {
58
119
  constructor() {
59
- super("errors.auth.invalidPassword", ERROR_CODES.AUTH.INVALID_CREDENTIALS);
120
+ super("auth.errors.invalidPassword", ERROR_CODES.AUTH.INVALID_CREDENTIALS);
60
121
  }
61
122
  };
62
123
  var InvalidEmailError = class extends ApplicationError {
63
124
  constructor(email) {
64
- super("errors.auth.invalidEmail", ERROR_CODES.VALIDATION.INVALID_FORMAT, email ? { email } : void 0);
125
+ super("auth.errors.invalidEmail", ERROR_CODES.VALIDATION.INVALID_FORMAT, email ? { email } : void 0);
65
126
  }
66
127
  };
67
128
  var SessionExpiredError = class extends ApplicationError {
68
129
  constructor() {
69
- super("errors.auth.sessionExpired", ERROR_CODES.AUTH.SESSION_EXPIRED);
130
+ super("auth.errors.sessionExpired", ERROR_CODES.AUTH.SESSION_EXPIRED);
70
131
  }
71
132
  };
72
133
  var EmailNotVerifiedError = class extends ApplicationError {
73
134
  constructor(email) {
74
- super("errors.auth.emailNotVerified", ERROR_CODES.AUTH.EMAIL_NOT_VERIFIED, email ? { email } : void 0);
135
+ super("auth.errors.emailNotVerified", ERROR_CODES.AUTH.EMAIL_NOT_VERIFIED, email ? { email } : void 0);
75
136
  }
76
137
  };
77
138
  var PasswordTooShortError = class extends ApplicationError {
78
139
  constructor(minLength) {
79
- super("errors.auth.passwordTooShort", ERROR_CODES.AUTH.PASSWORD_TOO_SHORT, { minLength });
140
+ super("auth.errors.passwordTooShort", ERROR_CODES.AUTH.PASSWORD_TOO_SHORT, { minLength });
80
141
  }
81
142
  };
82
143
  var PasswordTooLongError = class extends ApplicationError {
83
144
  constructor(maxLength) {
84
- super("errors.auth.passwordTooLong", ERROR_CODES.AUTH.PASSWORD_TOO_LONG, { maxLength });
145
+ super("auth.errors.passwordTooLong", ERROR_CODES.AUTH.PASSWORD_TOO_LONG, { maxLength });
85
146
  }
86
147
  };
87
148
  var AccountAlreadyExistsError = class extends ApplicationError {
88
149
  constructor(email) {
89
- super("errors.auth.accountAlreadyExists", ERROR_CODES.AUTH.ACCOUNT_ALREADY_EXISTS, email ? { email } : void 0);
150
+ super("auth.errors.accountAlreadyExists", ERROR_CODES.AUTH.ACCOUNT_ALREADY_EXISTS, email ? { email } : void 0);
90
151
  }
91
152
  };
92
153
  var FailedToCreateUserError = class extends ApplicationError {
93
154
  constructor(reason) {
94
- super("errors.auth.failedToCreateUser", ERROR_CODES.AUTH.FAILED_TO_CREATE_USER, reason ? { reason } : void 0);
155
+ super("auth.errors.failedToCreateUser", ERROR_CODES.AUTH.FAILED_TO_CREATE_USER, reason ? { reason } : void 0);
95
156
  }
96
157
  };
97
158
  var FailedToCreateSessionError = class extends ApplicationError {
98
159
  constructor(reason) {
99
- super("errors.auth.failedToCreateSession", ERROR_CODES.AUTH.FAILED_TO_CREATE_SESSION, reason ? { reason } : void 0);
160
+ super("auth.errors.failedToCreateSession", ERROR_CODES.AUTH.FAILED_TO_CREATE_SESSION, reason ? { reason } : void 0);
100
161
  }
101
162
  };
102
163
  var FailedToUpdateUserError = class extends ApplicationError {
103
164
  constructor(reason) {
104
- super("errors.auth.failedToUpdateUser", ERROR_CODES.AUTH.FAILED_TO_UPDATE_USER, reason ? { reason } : void 0);
165
+ super("auth.errors.failedToUpdateUser", ERROR_CODES.AUTH.FAILED_TO_UPDATE_USER, reason ? { reason } : void 0);
105
166
  }
106
167
  };
107
168
  var SocialAccountLinkedError = class extends ApplicationError {
108
169
  constructor(provider) {
109
- super("errors.auth.socialAccountLinked", ERROR_CODES.AUTH.SOCIAL_ACCOUNT_LINKED, provider ? { provider } : void 0);
170
+ super("auth.errors.socialAccountLinked", ERROR_CODES.AUTH.SOCIAL_ACCOUNT_LINKED, provider ? { provider } : void 0);
110
171
  }
111
172
  };
112
173
  var CannotUnlinkLastAccountError = class extends ApplicationError {
113
174
  constructor() {
114
- super("errors.auth.cannotUnlinkLastAccount", ERROR_CODES.AUTH.CANNOT_UNLINK_LAST_ACCOUNT);
175
+ super("auth.errors.cannotUnlinkLastAccount", ERROR_CODES.AUTH.CANNOT_UNLINK_LAST_ACCOUNT);
115
176
  }
116
177
  };
117
178
  var ProviderNotFoundError = class extends ApplicationError {
118
179
  constructor(provider) {
119
- super("errors.auth.providerNotFound", ERROR_CODES.RESOURCE.NOT_FOUND, provider ? { provider } : void 0);
180
+ super("auth.errors.providerNotFound", ERROR_CODES.RESOURCE.NOT_FOUND, provider ? { provider } : void 0);
120
181
  }
121
182
  };
122
183
  var UserEmailNotFoundError = class extends ApplicationError {
123
184
  constructor() {
124
- super("errors.auth.userEmailNotFound", ERROR_CODES.RESOURCE.NOT_FOUND);
185
+ super("auth.errors.userEmailNotFound", ERROR_CODES.RESOURCE.NOT_FOUND);
125
186
  }
126
187
  };
127
188
  var AccountNotFoundError = class extends ApplicationError {
128
189
  constructor() {
129
- super("errors.auth.accountNotFound", ERROR_CODES.RESOURCE.NOT_FOUND);
190
+ super("auth.errors.accountNotFound", ERROR_CODES.RESOURCE.NOT_FOUND);
130
191
  }
131
192
  };
132
193
  var CredentialAccountNotFoundError = class extends ApplicationError {
133
194
  constructor() {
134
- super("errors.auth.credentialAccountNotFound", ERROR_CODES.RESOURCE.NOT_FOUND);
195
+ super("auth.errors.credentialAccountNotFound", ERROR_CODES.RESOURCE.NOT_FOUND);
135
196
  }
136
197
  };
137
198
  var UserAlreadyHasPasswordError = class extends ApplicationError {
138
199
  constructor() {
139
- super("errors.auth.userAlreadyHasPassword", ERROR_CODES.RESOURCE.CONFLICT);
200
+ super("auth.errors.userAlreadyHasPassword", ERROR_CODES.RESOURCE.CONFLICT);
140
201
  }
141
202
  };
142
203
  var EmailCannotBeUpdatedError = class extends ApplicationError {
143
204
  constructor(reason) {
144
- super("errors.auth.emailCannotBeUpdated", ERROR_CODES.VALIDATION.GENERIC, reason ? { reason } : void 0);
205
+ super("auth.errors.emailCannotBeUpdated", ERROR_CODES.VALIDATION.GENERIC, reason ? { reason } : void 0);
145
206
  }
146
207
  };
147
208
  var FailedToGetSessionError = class extends ApplicationError {
148
209
  constructor(reason) {
149
- super("errors.auth.failedToGetSession", ERROR_CODES.SYSTEM.INTERNAL_ERROR, reason ? { reason } : void 0);
210
+ super("auth.errors.failedToGetSession", ERROR_CODES.SYSTEM.INTERNAL_ERROR, reason ? { reason } : void 0);
150
211
  }
151
212
  };
152
213
  var FailedToGetUserInfoError = class extends ApplicationError {
153
214
  constructor(reason) {
154
- super("errors.auth.failedToGetUserInfo", ERROR_CODES.SYSTEM.INTERNAL_ERROR, reason ? { reason } : void 0);
215
+ super("auth.errors.failedToGetUserInfo", ERROR_CODES.SYSTEM.INTERNAL_ERROR, reason ? { reason } : void 0);
155
216
  }
156
217
  };
157
218
  var IdTokenNotSupportedError = class extends ApplicationError {
158
219
  constructor() {
159
- super("errors.auth.invalidToken", ERROR_CODES.VALIDATION.GENERIC);
220
+ super("auth.errors.invalidToken", ERROR_CODES.VALIDATION.GENERIC);
160
221
  }
161
222
  };
162
223
  var TokenExpiredError = class extends ApplicationError {
163
224
  constructor() {
164
- super("errors.auth.tokenExpired", ERROR_CODES.VALIDATION.GENERIC);
225
+ super("auth.errors.tokenExpired", ERROR_CODES.VALIDATION.GENERIC);
226
+ }
227
+ };
228
+ var InvalidCallbackUrlError = class extends ApplicationError {
229
+ constructor() {
230
+ super("auth.errors.invalidCallbackUrl", ERROR_CODES.VALIDATION.INVALID_FORMAT);
231
+ }
232
+ };
233
+ var InvalidOriginError = class extends ApplicationError {
234
+ constructor() {
235
+ super("auth.errors.invalidOrigin", ERROR_CODES.AUTHZ.FORBIDDEN);
236
+ }
237
+ };
238
+ var AuthValidationFailedError = class extends ApplicationError {
239
+ constructor() {
240
+ super("auth.errors.validationFailed", ERROR_CODES.VALIDATION.GENERIC);
241
+ }
242
+ };
243
+ var EmailAlreadyVerifiedError = class extends ApplicationError {
244
+ constructor() {
245
+ super("auth.errors.emailAlreadyVerified", ERROR_CODES.RESOURCE.CONFLICT);
246
+ }
247
+ };
248
+ var EmailMismatchError = class extends ApplicationError {
249
+ constructor() {
250
+ super("auth.errors.emailMismatch", ERROR_CODES.VALIDATION.INVALID_FORMAT);
251
+ }
252
+ };
253
+ var BetterAuthUnknownError = class extends ApplicationError {
254
+ constructor(errorCode) {
255
+ super("auth.errors.unknownError", ERROR_CODES.SYSTEM.INTERNAL_ERROR, errorCode ? { errorCode } : void 0);
165
256
  }
166
257
  };
167
258
  //#endregion
168
259
  //#region src/auth/errors/invalid-token.error.ts
169
260
  var InvalidTokenError = class extends ApplicationError {
170
261
  constructor() {
171
- super("errors.auth.invalidToken", ERROR_CODES.AUTH.INVALID_TOKEN);
262
+ super("auth.errors.invalidToken", ERROR_CODES.AUTH.INVALID_TOKEN);
263
+ }
264
+ };
265
+ //#endregion
266
+ //#region src/auth/errors/organization-errors.ts
267
+ var OrganizationNotFoundError = class extends ApplicationError {
268
+ constructor() {
269
+ super("auth.org.organizationNotFound", ERROR_CODES.AUTH.ORGANIZATION_NOT_FOUND);
270
+ }
271
+ };
272
+ var OrganizationMemberNotFoundError = class extends ApplicationError {
273
+ constructor() {
274
+ super("auth.org.memberNotFound", ERROR_CODES.AUTH.MEMBER_NOT_FOUND);
275
+ }
276
+ };
277
+ var OrganizationInvitationNotFoundError = class extends ApplicationError {
278
+ constructor() {
279
+ super("auth.org.invitationNotFound", ERROR_CODES.AUTH.INVITATION_NOT_FOUND);
280
+ }
281
+ };
282
+ var OrganizationPermissionDeniedError = class extends ApplicationError {
283
+ constructor() {
284
+ super("auth.org.permissionDenied", ERROR_CODES.AUTHZ.FORBIDDEN);
285
+ }
286
+ };
287
+ var OrganizationInvitationRecipientMismatchError = class extends ApplicationError {
288
+ constructor() {
289
+ super("auth.org.invitationRecipientMismatch", ERROR_CODES.AUTH.INVITATION_RECIPIENT_MISMATCH);
290
+ }
291
+ };
292
+ var OrganizationConflictError = class extends ApplicationError {
293
+ constructor() {
294
+ super("auth.org.conflict", ERROR_CODES.RESOURCE.CONFLICT);
295
+ }
296
+ };
297
+ var OrganizationLimitReachedError = class extends ApplicationError {
298
+ constructor() {
299
+ super("auth.org.limitReached", ERROR_CODES.AUTH.ORGANIZATION_LIMIT_REACHED);
300
+ }
301
+ };
302
+ var OrganizationMembershipError = class extends ApplicationError {
303
+ constructor() {
304
+ super("auth.org.membershipError", ERROR_CODES.AUTH.ORGANIZATION_MEMBERSHIP_REQUIRED);
305
+ }
306
+ };
307
+ var OrganizationTeamNotFoundError = class extends ApplicationError {
308
+ constructor() {
309
+ super("auth.org.teamNotFound", ERROR_CODES.RESOURCE.NOT_FOUND);
310
+ }
311
+ };
312
+ var OrganizationRoleNotFoundError = class extends ApplicationError {
313
+ constructor() {
314
+ super("auth.org.roleNotFound", ERROR_CODES.RESOURCE.NOT_FOUND);
172
315
  }
173
316
  };
174
317
  //#endregion
175
318
  //#region src/auth/errors/token-required.error.ts
176
319
  var TokenRequiredError = class extends ApplicationError {
177
320
  constructor() {
178
- super("errors.auth.tokenRequired", ERROR_CODES.VALIDATION.REQUIRED_FIELD, { field: "token" });
321
+ super("auth.errors.tokenRequired", ERROR_CODES.VALIDATION.REQUIRED_FIELD, { field: "token" });
179
322
  }
180
323
  };
181
324
  //#endregion
182
325
  //#region src/auth/errors/verification-failed.error.ts
183
326
  var VerificationFailedError = class extends ApplicationError {
184
327
  constructor() {
185
- super("errors.auth.verificationFailed", ERROR_CODES.AUTH.INVALID_CREDENTIALS);
328
+ super("auth.errors.verificationFailed", ERROR_CODES.AUTH.INVALID_CREDENTIALS);
186
329
  }
187
330
  };
188
331
  //#endregion
@@ -193,22 +336,27 @@ var VerificationFailedError = class extends ApplicationError {
193
336
  function mapBetterAuthError(error) {
194
337
  const errorCode = error.body?.code;
195
338
  if (error.status === "FOUND") {
196
- if (error.headers.get("location")?.includes("INVALID_TOKEN")) return new InvalidTokenError();
197
- }
198
- if (!errorCode) return new InternalError({
199
- originalError: `Better Auth error: ${error.message}`,
200
- stack: error.stack
201
- });
202
- if (errorCode === "USER_NOT_FOUND") return new UserNotFoundError();
339
+ const location = error.headers.get("location") ?? "";
340
+ if (location.includes("INVALID_TOKEN")) return new InvalidTokenError();
341
+ if (location.includes("EXPIRED_TOKEN")) return new TokenExpiredError();
342
+ if (location.includes("ATTEMPTS_EXCEEDED")) return new InvalidTokenError();
343
+ if (location.includes("new_user_signup_disabled")) return new UserNotFoundError();
344
+ if (location.includes("failed_to_create_user")) return new FailedToCreateUserError();
345
+ if (location.includes("failed_to_create_session")) return new FailedToCreateSessionError();
346
+ }
347
+ if (!errorCode) return new BetterAuthUnknownError();
348
+ if (errorCode === "USER_NOT_FOUND" || errorCode === "INVALID_USER") return new UserNotFoundError();
203
349
  if (errorCode === "USER_EMAIL_NOT_FOUND") return new UserEmailNotFoundError();
204
350
  if (errorCode === "INVALID_EMAIL_OR_PASSWORD") return new InvalidCredentialsError();
205
351
  if (errorCode === "INVALID_PASSWORD") return new InvalidPasswordError();
206
352
  if (errorCode === "INVALID_EMAIL") return new InvalidEmailError();
207
- if (errorCode === "SESSION_EXPIRED") return new SessionExpiredError();
353
+ if (errorCode === "SESSION_EXPIRED" || errorCode === "SESSION_NOT_FRESH") return new SessionExpiredError();
208
354
  if (errorCode === "FAILED_TO_CREATE_SESSION") return new FailedToCreateSessionError();
209
355
  if (errorCode === "FAILED_TO_GET_SESSION") return new FailedToGetSessionError();
210
356
  if (errorCode === "EMAIL_NOT_VERIFIED") return new EmailNotVerifiedError();
211
357
  if (errorCode === "EMAIL_CAN_NOT_BE_UPDATED") return new EmailCannotBeUpdatedError();
358
+ if (errorCode === "EMAIL_ALREADY_VERIFIED") return new EmailAlreadyVerifiedError();
359
+ if (errorCode === "EMAIL_MISMATCH") return new EmailMismatchError();
212
360
  if (errorCode === "PASSWORD_TOO_SHORT") return new PasswordTooShortError(8);
213
361
  if (errorCode === "PASSWORD_TOO_LONG") return new PasswordTooLongError(128);
214
362
  if (errorCode === "USER_ALREADY_EXISTS" || errorCode === "USER_ALREADY_EXISTS_USE_ANOTHER_EMAIL") return new AccountAlreadyExistsError();
@@ -218,22 +366,36 @@ function mapBetterAuthError(error) {
218
366
  if (errorCode === "FAILED_TO_CREATE_USER") return new FailedToCreateUserError();
219
367
  if (errorCode === "FAILED_TO_UPDATE_USER") return new FailedToUpdateUserError();
220
368
  if (errorCode === "FAILED_TO_GET_USER_INFO") return new FailedToGetUserInfoError();
221
- if (errorCode === "SOCIAL_ACCOUNT_ALREADY_LINKED") return new SocialAccountLinkedError();
369
+ if (errorCode === "SOCIAL_ACCOUNT_ALREADY_LINKED" || errorCode === "LINKED_ACCOUNT_ALREADY_EXISTS") return new SocialAccountLinkedError();
222
370
  if (errorCode === "PROVIDER_NOT_FOUND") return new ProviderNotFoundError();
223
371
  if (errorCode === "ID_TOKEN_NOT_SUPPORTED") return new IdTokenNotSupportedError();
224
- if (errorCode === "INVALID_TOKEN") return new IdTokenNotSupportedError();
372
+ if (errorCode === "INVALID_TOKEN") return new InvalidTokenError();
225
373
  if (errorCode === "TOKEN_EXPIRED") return new TokenExpiredError();
226
- if (errorCode === "USER_ALREADY_HAS_PASSWORD") return new UserAlreadyHasPasswordError();
227
- return new InternalError({
228
- originalError: `Better Auth error [${errorCode}]: ${error.message}`,
229
- stack: error.stack
230
- });
374
+ if (errorCode === "USER_ALREADY_HAS_PASSWORD" || errorCode === "PASSWORD_ALREADY_SET") return new UserAlreadyHasPasswordError();
375
+ if (errorCode === "INVALID_CALLBACK_URL" || errorCode === "INVALID_REDIRECT_URL" || errorCode === "INVALID_NEW_USER_CALLBACK_URL" || errorCode === "INVALID_ERROR_CALLBACK_URL" || errorCode === "CALLBACK_URL_REQUIRED") return new InvalidCallbackUrlError();
376
+ if (errorCode === "INVALID_ORIGIN" || errorCode === "MISSING_OR_NULL_ORIGIN" || errorCode === "CROSS_SITE_NAVIGATION_LOGIN_BLOCKED") return new InvalidOriginError();
377
+ if (errorCode === "VALIDATION_ERROR" || errorCode === "MISSING_FIELD" || errorCode === "FIELD_NOT_ALLOWED" || errorCode === "BODY_MUST_BE_AN_OBJECT" || errorCode === "ASYNC_VALIDATION_NOT_SUPPORTED" || errorCode === "METHOD_NOT_ALLOWED_DEFER_SESSION_REQUIRED") return new AuthValidationFailedError();
378
+ if (errorCode === "FAILED_TO_CREATE_VERIFICATION" || errorCode === "VERIFICATION_EMAIL_NOT_ENABLED") return new FailedToCreateSessionError();
379
+ if (errorCode === "ORGANIZATION_NOT_FOUND" || errorCode === "NO_ACTIVE_ORGANIZATION") return new OrganizationNotFoundError();
380
+ if (errorCode === "MEMBER_NOT_FOUND" || errorCode === "USER_IS_NOT_A_MEMBER_OF_THE_ORGANIZATION" || errorCode === "USER_IS_NOT_A_MEMBER_OF_THE_TEAM") return new OrganizationMemberNotFoundError();
381
+ if (errorCode === "INVITATION_NOT_FOUND" || errorCode === "FAILED_TO_RETRIEVE_INVITATION") return new OrganizationInvitationNotFoundError();
382
+ if (errorCode === "YOU_ARE_NOT_THE_RECIPIENT_OF_THE_INVITATION" || errorCode === "EMAIL_VERIFICATION_REQUIRED_BEFORE_ACCEPTING_OR_REJECTING_INVITATION") return new OrganizationInvitationRecipientMismatchError();
383
+ if (errorCode === "TEAM_NOT_FOUND" || errorCode === "YOU_DO_NOT_HAVE_AN_ACTIVE_TEAM") return new OrganizationTeamNotFoundError();
384
+ if (errorCode === "ROLE_NOT_FOUND" || errorCode === "INVALID_RESOURCE") return new OrganizationRoleNotFoundError();
385
+ if (errorCode === "ORGANIZATION_ALREADY_EXISTS" || errorCode === "ORGANIZATION_SLUG_ALREADY_TAKEN" || errorCode === "USER_IS_ALREADY_A_MEMBER_OF_THIS_ORGANIZATION" || errorCode === "USER_IS_ALREADY_INVITED_TO_THIS_ORGANIZATION" || errorCode === "TEAM_ALREADY_EXISTS" || errorCode === "ROLE_NAME_IS_ALREADY_TAKEN") return new OrganizationConflictError();
386
+ if (errorCode === "YOU_HAVE_REACHED_THE_MAXIMUM_NUMBER_OF_ORGANIZATIONS" || errorCode === "YOU_HAVE_REACHED_THE_MAXIMUM_NUMBER_OF_TEAMS" || errorCode === "ORGANIZATION_MEMBERSHIP_LIMIT_REACHED" || errorCode === "INVITATION_LIMIT_REACHED" || errorCode === "TEAM_MEMBER_LIMIT_REACHED" || errorCode === "TOO_MANY_ROLES") return new OrganizationLimitReachedError();
387
+ if (errorCode === "YOU_CANNOT_LEAVE_THE_ORGANIZATION_AS_THE_ONLY_OWNER" || errorCode === "YOU_CANNOT_LEAVE_THE_ORGANIZATION_WITHOUT_AN_OWNER" || errorCode === "UNABLE_TO_REMOVE_LAST_TEAM" || errorCode === "CANNOT_DELETE_A_PRE_DEFINED_ROLE" || errorCode === "ROLE_IS_ASSIGNED_TO_MEMBERS" || errorCode === "YOU_CANNOT_IMPERSONATE_ADMINS" || errorCode === "YOU_CANNOT_BAN_YOURSELF" || errorCode === "YOU_CANNOT_REMOVE_YOURSELF" || errorCode === "INVITER_IS_NO_LONGER_A_MEMBER_OF_THE_ORGANIZATION") return new OrganizationMembershipError();
388
+ if (errorCode.startsWith("YOU_ARE_NOT_ALLOWED_TO_") || errorCode === "YOU_ARE_NOT_A_MEMBER_OF_THIS_ORGANIZATION" || errorCode === "YOU_CAN_NOT_ACCESS_THE_MEMBERS_OF_THIS_TEAM" || errorCode === "YOU_MUST_BE_IN_AN_ORGANIZATION_TO_CREATE_A_ROLE" || errorCode === "MISSING_AC_INSTANCE") return new OrganizationPermissionDeniedError();
389
+ return new BetterAuthUnknownError(errorCode);
231
390
  }
232
391
  /**
233
- * Type guard to check if an error is a Better Auth APIError
392
+ * Type guard to check if an error is a Better Auth APIError.
393
+ * Uses duck typing to handle bundler environments (e.g. Vite)
394
+ * where instanceof may fail across module boundaries.
234
395
  */
235
396
  function isAPIError(error) {
236
- return error instanceof APIError;
397
+ if (error instanceof APIError) return true;
398
+ return error instanceof Error && error.name === "APIError" && "status" in error && "statusCode" in error;
237
399
  }
238
400
  //#endregion
239
401
  //#region src/auth/utils/auth-helpers.ts
@@ -281,7 +443,7 @@ let AuthService = class AuthService {
281
443
  };
282
444
  AuthService = __decorate([
283
445
  Transient(AUTH_SERVICE),
284
- __decorateParam(0, inject(AUTH_OPTIONS)),
446
+ __decorateParam(0, inject$1(AUTH_OPTIONS)),
285
447
  __decorateMetadata("design:paramtypes", [Object])
286
448
  ], AuthService);
287
449
  //#endregion
@@ -289,35 +451,60 @@ AuthService = __decorate([
289
451
  var _AuthModule;
290
452
  let AuthModule = _AuthModule = class AuthModule {
291
453
  /**
292
- * Configure auth middleware.
454
+ * Configure auth middleware globally.
293
455
  *
294
456
  * Registers middlewares in order:
295
457
  * 1. AuthContextMiddleware - Creates and registers AuthContext in request container
296
- * 2. SessionVerificationMiddleware - Verifies session and populates AuthContext with userId
458
+ * 2. SessionVerificationMiddleware - Verifies session and populates AuthContext with userId + role
297
459
  */
298
- configure(consumer) {
299
- consumer.apply(AuthContextMiddleware).forRoutes("*");
300
- consumer.apply(SessionVerificationMiddleware).forRoutes("*");
460
+ configureRoutes(router) {
461
+ router.use(AuthContextMiddleware, SessionVerificationMiddleware);
301
462
  }
302
463
  /**
303
- * Configure AuthModule with async options factory
464
+ * Configure AuthModule with async options factory.
465
+ * Optionally provide `accessControl` to enable permission-based authorization.
304
466
  */
305
467
  static forRootAsync(options) {
468
+ const { accessControl } = options;
469
+ const authOptionsProvider = accessControl ? {
470
+ provide: AUTH_OPTIONS,
471
+ useFactory: (...deps) => {
472
+ const raw = options.useFactory(...deps);
473
+ return {
474
+ ...raw,
475
+ plugins: [createStratalAcPlugin(accessControl), ...raw.plugins ?? []]
476
+ };
477
+ },
478
+ inject: options.inject
479
+ } : {
480
+ provide: AUTH_OPTIONS,
481
+ useFactory: options.useFactory,
482
+ inject: options.inject
483
+ };
306
484
  return {
307
485
  module: _AuthModule,
308
- providers: [{
309
- provide: AUTH_OPTIONS,
310
- useFactory: options.useFactory,
311
- inject: options.inject
312
- }, {
313
- provide: AUTH_SERVICE,
314
- useClass: AuthService
315
- }]
486
+ providers: [
487
+ authOptionsProvider,
488
+ {
489
+ provide: AUTH_SERVICE,
490
+ useClass: AuthService
491
+ },
492
+ ...accessControl ? [{
493
+ provide: AC_TOKENS.Options,
494
+ useValue: accessControl
495
+ }, {
496
+ provide: AC_TOKENS.AccessService,
497
+ useClass: AccessService
498
+ }] : []
499
+ ]
316
500
  };
317
501
  }
318
502
  };
319
- AuthModule = _AuthModule = __decorate([Module({ providers: [] })], AuthModule);
503
+ AuthModule = _AuthModule = __decorate([Module({
504
+ imports: [I18nModule.registerMessages(authMessages)],
505
+ providers: []
506
+ })], AuthModule);
320
507
  //#endregion
321
- export { AUTH_OPTIONS, AUTH_SERVICE, AccountAlreadyExistsError, AccountNotFoundError, AuthContextMiddleware, AuthModule, AuthService, CannotUnlinkLastAccountError, CredentialAccountNotFoundError, EmailCannotBeUpdatedError, EmailNotVerifiedError, FailedToCreateSessionError, FailedToCreateUserError, FailedToGetSessionError, FailedToGetUserInfoError, FailedToUpdateUserError, IdTokenNotSupportedError, InvalidCredentialsError, InvalidEmailError, InvalidPasswordError, InvalidTokenError, PasswordTooLongError, PasswordTooShortError, ProviderNotFoundError, SessionExpiredError, SessionVerificationMiddleware, SocialAccountLinkedError, TokenExpiredError, TokenRequiredError, UserAlreadyHasPasswordError, UserEmailNotFoundError, UserNotFoundError, VerificationFailedError, getErrorHandlerConfig, isAPIError, mapBetterAuthError, wrapBetterAuth };
508
+ export { AUTH_OPTIONS, AUTH_SERVICE, AccountAlreadyExistsError, AccountNotFoundError, AuthContextMiddleware, AuthModule, AuthService, AuthValidationFailedError, BetterAuthUnknownError, CannotUnlinkLastAccountError, CredentialAccountNotFoundError, EmailAlreadyVerifiedError, EmailCannotBeUpdatedError, EmailMismatchError, EmailNotVerifiedError, FailedToCreateSessionError, FailedToCreateUserError, FailedToGetSessionError, FailedToGetUserInfoError, FailedToUpdateUserError, IdTokenNotSupportedError, InvalidCallbackUrlError, InvalidCredentialsError, InvalidEmailError, InvalidOriginError, InvalidPasswordError, InvalidTokenError, OrganizationConflictError, OrganizationInvitationNotFoundError, OrganizationInvitationRecipientMismatchError, OrganizationLimitReachedError, OrganizationMemberNotFoundError, OrganizationMembershipError, OrganizationNotFoundError, OrganizationPermissionDeniedError, OrganizationRoleNotFoundError, OrganizationTeamNotFoundError, PasswordTooLongError, PasswordTooShortError, ProviderNotFoundError, SessionExpiredError, SessionVerificationMiddleware, SocialAccountLinkedError, TokenExpiredError, TokenRequiredError, UserAlreadyHasPasswordError, UserEmailNotFoundError, UserNotFoundError, VerificationFailedError, authMessages, getErrorHandlerConfig, isAPIError, mapBetterAuthError, wrapBetterAuth };
322
509
 
323
510
  //# sourceMappingURL=index.mjs.map