firstly 0.0.12 → 0.0.13

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 (83) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/esm/api/index.d.ts +1 -0
  3. package/esm/api/index.js +3 -1
  4. package/esm/auth/server/AuthController.server.d.ts +1 -1
  5. package/esm/auth/server/AuthController.server.js +19 -19
  6. package/esm/auth/server/handleGuard.d.ts +16 -0
  7. package/esm/auth/server/handleGuard.js +67 -0
  8. package/esm/auth/server/index.d.ts +3 -1
  9. package/esm/auth/server/index.js +3 -1
  10. package/esm/auth/server/module.d.ts +102 -83
  11. package/esm/auth/server/module.js +55 -42
  12. package/esm/auth/server/providers/github.d.ts +2 -1
  13. package/esm/auth/server/providers/github.js +1 -1
  14. package/esm/auth/static/assets/Page-BUfjaN-D.d.ts +5 -0
  15. package/esm/auth/static/assets/Page-BUfjaN-D.js +19 -0
  16. package/esm/auth/static/assets/Page-CJ58H1vl.css +1 -0
  17. package/esm/auth/static/assets/Page-CaDAqmBS.d.ts +5 -0
  18. package/esm/auth/static/assets/Page-CaDAqmBS.js +1 -0
  19. package/esm/auth/static/assets/Page-DhdZddzJ.d.ts +5 -0
  20. package/esm/auth/static/assets/Page-DhdZddzJ.js +1 -0
  21. package/esm/auth/static/assets/index-BDy4A_14.css +4 -0
  22. package/esm/auth/static/assets/index-D-Ztdt2o.d.ts +54 -0
  23. package/esm/auth/static/assets/index-D-Ztdt2o.js +2 -0
  24. package/esm/auth/static/index.html +11 -11
  25. package/esm/bin/cmd.js +119 -48
  26. package/esm/cellsBuildor.js +1 -1
  27. package/esm/common.d.ts +5 -0
  28. package/esm/common.js +8 -0
  29. package/esm/cron/server/index.js +1 -1
  30. package/esm/feedback/FeedbackController.js +1 -2
  31. package/esm/feedback/ui/DialogIssue.svelte +52 -56
  32. package/esm/feedback/ui/DialogIssues.svelte +71 -71
  33. package/esm/feedback/ui/DialogMilestones.svelte +22 -22
  34. package/esm/index.d.ts +2 -5
  35. package/esm/index.js +2 -8
  36. package/esm/mail/templates/DefaultMail.svelte +17 -17
  37. package/esm/storeItem.d.ts +1 -4
  38. package/esm/storeItem.js +1 -1
  39. package/esm/storeList.d.ts +1 -4
  40. package/esm/sveltekit/server/index.d.ts +3 -0
  41. package/esm/sveltekit/server/index.js +3 -0
  42. package/esm/ui/Button.svelte +33 -33
  43. package/esm/ui/Button.svelte.d.ts +2 -2
  44. package/esm/ui/Clipboardable.svelte +6 -6
  45. package/esm/ui/Clipboardable.svelte.d.ts +4 -4
  46. package/esm/ui/Field.svelte +139 -149
  47. package/esm/ui/Field.svelte.d.ts +2 -2
  48. package/esm/ui/FieldGroup.svelte +38 -38
  49. package/esm/ui/Grid.svelte +212 -222
  50. package/esm/ui/GridLoading.svelte +18 -22
  51. package/esm/ui/GridPaginate.svelte +38 -38
  52. package/esm/ui/Icon.svelte +50 -49
  53. package/esm/ui/Icon.svelte.d.ts +18 -18
  54. package/esm/ui/Loading.svelte +5 -5
  55. package/esm/ui/Tooltip.svelte +16 -16
  56. package/esm/ui/dialog/DialogForm.svelte +22 -22
  57. package/esm/ui/dialog/DialogManagement.svelte +74 -74
  58. package/esm/ui/dialog/DialogPrimitive.svelte +50 -50
  59. package/esm/ui/dialog/FormEditAction.svelte +34 -34
  60. package/esm/ui/dialog/dialog.d.ts +1 -4
  61. package/esm/ui/internals/FieldContainer.svelte +11 -11
  62. package/esm/ui/internals/FieldContainer.svelte.d.ts +3 -3
  63. package/esm/ui/internals/Input.svelte +25 -25
  64. package/esm/ui/internals/Input.svelte.d.ts +1 -1
  65. package/esm/ui/internals/Textarea.svelte +21 -21
  66. package/esm/ui/internals/Textarea.svelte.d.ts +2 -2
  67. package/esm/ui/internals/select/MultiSelectMelt.svelte +69 -73
  68. package/esm/ui/internals/select/SelectMelt.svelte +86 -86
  69. package/esm/ui/internals/select/SelectRadio.svelte +22 -22
  70. package/esm/ui/link/Link.svelte +14 -14
  71. package/esm/ui/link/Link.svelte.d.ts +3 -4
  72. package/esm/ui/link/LinkPlus.svelte +33 -35
  73. package/package.json +14 -18
  74. package/esm/auth/static/assets/Page-Bb8bFlrP.d.ts +0 -4
  75. package/esm/auth/static/assets/Page-Bb8bFlrP.js +0 -1
  76. package/esm/auth/static/assets/Page-BxomFlZ8.d.ts +0 -4
  77. package/esm/auth/static/assets/Page-BxomFlZ8.js +0 -1
  78. package/esm/auth/static/assets/Page-CaIYu0-y.d.ts +0 -6
  79. package/esm/auth/static/assets/Page-CaIYu0-y.js +0 -19
  80. package/esm/auth/static/assets/Page-MkYglNtu.css +0 -1
  81. package/esm/auth/static/assets/index-Bl0Bk5u0.d.ts +0 -64
  82. package/esm/auth/static/assets/index-Bl0Bk5u0.js +0 -2
  83. package/esm/auth/static/assets/index-R27C_TlP.css +0 -4
package/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # firstly
2
2
 
3
+ ## 0.0.13
4
+
5
+ ### Patch Changes
6
+
7
+ - [#66](https://github.com/jycouet/firstly/pull/66)
8
+ [`7d8b323`](https://github.com/jycouet/firstly/commit/7d8b323b49d7d76b6d59ec887ed2e37a2238f201)
9
+ Thanks [@jycouet](https://github.com/jycouet)! - prepare JYC 013
10
+
3
11
  ## 0.0.12
4
12
 
5
13
  ### Patch Changes
@@ -31,6 +31,7 @@ type Options = RemultServerOptions<RequestEvent<Partial<Record<string, string>>,
31
31
  export declare let entities: ClassType<any>[];
32
32
  /**
33
33
  * it's basically `remultSveltekit` with the `modules` option
34
+ * @deprecated will be done directly in remult when modules will be in 😉
34
35
  */
35
36
  export declare const firstly: (o: Options) => import("remult/remult-sveltekit").RemultSveltekitServer;
36
37
  /**
package/esm/api/index.js CHANGED
@@ -2,6 +2,7 @@ import {} from 'remult';
2
2
  import { remultSveltekit } from 'remult/remult-sveltekit';
3
3
  import { Log } from '@kitql/helpers';
4
4
  import { building } from '$app/environment';
5
+ import { sveltekit } from '../sveltekit/server';
5
6
  export class Module {
6
7
  name;
7
8
  log;
@@ -25,10 +26,11 @@ export class Module {
25
26
  export let entities = [];
26
27
  /**
27
28
  * it's basically `remultSveltekit` with the `modules` option
29
+ * @deprecated will be done directly in remult when modules will be in 😉
28
30
  */
29
31
  export const firstly = (o) => {
30
32
  const modulesSorted = modulesFlatAndOrdered([
31
- ...(o.modules ?? []),
33
+ ...[...(o.modules ?? []), sveltekit()],
32
34
  new Module({
33
35
  name: 'default',
34
36
  entities: o.entities ?? [],
@@ -26,7 +26,7 @@ export declare class AuthControllerServer {
26
26
  /**
27
27
  * Forgot your password ? Send a mail to reset it.
28
28
  */
29
- static forgotPassword(emailParam: string): Promise<"Mail sent !" | "Demo Mail sent !">;
29
+ static forgotPassword(emailParam: string): Promise<string>;
30
30
  /**
31
31
  * Reset your password with a token
32
32
  */
@@ -44,7 +44,7 @@ export class AuthControllerServer {
44
44
  user.roles = r.roles;
45
45
  await repo(oSafe.User).save(user);
46
46
  await ff_createSession(user.id);
47
- return "You're in with demo account!";
47
+ return `You're in with ${name} demo account!`;
48
48
  }
49
49
  /**
50
50
  * This is for login / password authentication invite
@@ -68,14 +68,13 @@ export class AuthControllerServer {
68
68
  // const user = await repo(oSafe.User).insert({
69
69
  // identifier: email,
70
70
  // })
71
- oSafe.providers?.password?.verifyMailExpiresIn;
72
71
  await repo(oSafe.Account).insert({
73
72
  provider: FFAuthProvider.PASSWORD.id,
74
73
  providerUserId: email,
75
74
  // userId: user.id,
76
75
  // hashPassword: await passwordHash(password),
77
76
  token: token,
78
- expiresAt: createDate(AUTH_OPTIONS.providers?.password?.verifyMailExpiresIn ?? 5 * 60),
77
+ expiresAt: createDate(AUTH_OPTIONS.providers?.password?.mail?.verify?.expiresIn ?? 5 * 60),
79
78
  lastVerifiedAt: undefined,
80
79
  });
81
80
  const url = `${remult.context.request.url.origin}${oSafe.firstlyData.props.ui?.paths.reset_password}?token=${token}`;
@@ -117,14 +116,15 @@ export class AuthControllerServer {
117
116
  * _(The first param `email` can be "anything")_
118
117
  */
119
118
  static async signUpPassword(emailParam, password) {
120
- const email = emailParam.toLowerCase();
121
119
  const oSafe = getSafeOptions();
122
120
  if (!oSafe.signUp) {
123
- throw new EntityError({ message: "You can't signup by yourself! Contact the administrator." });
121
+ throw new EntityError({ message: oSafe.strings.cannotSignUp });
124
122
  }
125
123
  if (!oSafe.password.enabled) {
126
124
  throw new EntityError({ message: 'Password is not enabled!' });
127
125
  }
126
+ const email = emailParam.toLowerCase();
127
+ oSafe.password.validateInput({ identifier: email, password });
128
128
  const existingAccount = await repo(oSafe.Account).findOne({
129
129
  where: {
130
130
  providerUserId: email,
@@ -134,7 +134,6 @@ export class AuthControllerServer {
134
134
  if (existingAccount) {
135
135
  throw new EntityError({ message: "You can't signup twice !" });
136
136
  }
137
- oSafe.password.validatePassword(password);
138
137
  const token = generateAndEncodeToken();
139
138
  await remult.dataProvider.transaction(async () => {
140
139
  const user = await repo(oSafe.User).insert({
@@ -144,11 +143,11 @@ export class AuthControllerServer {
144
143
  provider: FFAuthProvider.PASSWORD.id,
145
144
  providerUserId: email,
146
145
  userId: user.id,
147
- hashPassword: oSafe.password.passwordHash(password),
146
+ hashPassword: await oSafe.password.hash(password),
148
147
  token: oSafe.verifiedMethod === 'auto' ? undefined : token,
149
148
  expiresAt: oSafe.verifiedMethod === 'auto'
150
149
  ? undefined
151
- : createDate(AUTH_OPTIONS.providers?.password?.verifyMailExpiresIn ?? 5 * 60),
150
+ : createDate(AUTH_OPTIONS.providers?.password?.mail?.verify?.expiresIn ?? 5 * 60),
152
151
  lastVerifiedAt: oSafe.verifiedMethod === 'auto' ? new Date() : undefined,
153
152
  });
154
153
  });
@@ -162,8 +161,8 @@ export class AuthControllerServer {
162
161
  }
163
162
  else {
164
163
  const url = `${remult.context.request.url.origin}${oSafe.firstlyData.props.ui?.paths.verify_email}?token=${token}`;
165
- if (AUTH_OPTIONS.providers?.password?.verifyMailSend) {
166
- await AUTH_OPTIONS.providers?.password.verifyMailSend({ email, url });
164
+ if (AUTH_OPTIONS.providers?.password?.mail?.verify?.send) {
165
+ await AUTH_OPTIONS.providers?.password.mail.verify.send({ email, url });
167
166
  authModuleRaw.log.success(`${green('[custom]')}${magenta('[verifyMailSend]')} (${yellow(url)})`);
168
167
  }
169
168
  else {
@@ -196,6 +195,7 @@ export class AuthControllerServer {
196
195
  static async signInPassword(emailParam, password) {
197
196
  const email = emailParam.toLowerCase();
198
197
  const oSafe = getSafeOptions();
198
+ oSafe.password.validateInput({ identifier: email, password });
199
199
  if (!oSafe.password.enabled) {
200
200
  throw new EntityError({ message: 'Password is not enabled!' });
201
201
  }
@@ -206,7 +206,7 @@ export class AuthControllerServer {
206
206
  },
207
207
  });
208
208
  if (existingAccount) {
209
- const validPassword = oSafe.password.passwordVerify(password ?? '', existingAccount?.hashPassword ?? '');
209
+ const validPassword = oSafe.password.verify(password ?? '', existingAccount?.hashPassword ?? '');
210
210
  if (validPassword) {
211
211
  await ff_createSession(existingAccount.userId);
212
212
  return 'ok';
@@ -235,13 +235,13 @@ export class AuthControllerServer {
235
235
  if (existingAccount) {
236
236
  const token = generateAndEncodeToken();
237
237
  existingAccount.token = token;
238
- existingAccount.expiresAt = createDate(AUTH_OPTIONS.providers?.password?.resetPasswordExpiresIn ?? 5 * 60);
238
+ existingAccount.expiresAt = createDate(AUTH_OPTIONS.providers?.password?.mail?.reset?.expiresIn ?? 5 * 60);
239
239
  await repo(oSafe.Account).save(existingAccount);
240
240
  const url = `${remult.context.request.url.origin}${oSafe.firstlyData.props.ui?.paths.reset_password}?token=${token}`;
241
- if (AUTH_OPTIONS.providers?.password?.resetPasswordSend) {
242
- await AUTH_OPTIONS.providers?.password.resetPasswordSend({ email, url });
241
+ if (AUTH_OPTIONS.providers?.password?.mail?.reset?.send) {
242
+ await AUTH_OPTIONS.providers?.password.mail.reset.send({ email, url });
243
243
  authModuleRaw.log.success(`${green('[custom]')}${magenta('[resetPasswordSend]')} (${yellow(url)})`);
244
- return 'Mail sent !';
244
+ return oSafe.strings.resetPasswordSend;
245
245
  }
246
246
  else {
247
247
  await sendMail('resetPasswordSend', {
@@ -266,10 +266,10 @@ export class AuthControllerServer {
266
266
  },
267
267
  });
268
268
  authModuleRaw.log.success(`${magenta('[resetPasswordSend]')} (${yellow(url)})`);
269
- return 'Demo Mail sent !';
269
+ return `Demo | ${oSafe.strings.resetPasswordSend}`;
270
270
  }
271
271
  }
272
- throw new EntityError({ message: "Une erreur est survenue, contacte l'administrateur!" });
272
+ throw new EntityError({ message: oSafe.strings.anErrorOccurred });
273
273
  }
274
274
  /**
275
275
  * Reset your password with a token
@@ -279,6 +279,7 @@ export class AuthControllerServer {
279
279
  if (!oSafe.password.enabled) {
280
280
  throw new EntityError({ message: 'Password is not enabled!' });
281
281
  }
282
+ oSafe.password.validateInput({ identifier: 'resetPassword', password });
282
283
  const account = await remult
283
284
  .repo(oSafe.Account)
284
285
  .findFirst({ token, provider: FFAuthProvider.PASSWORD.id });
@@ -288,14 +289,13 @@ export class AuthControllerServer {
288
289
  if (account.expiresAt && account.expiresAt < new Date()) {
289
290
  throw new EntityError({ message: 'token expired' });
290
291
  }
291
- oSafe.password.validatePassword(password);
292
292
  if (account.userId === undefined) {
293
293
  const user = await repo(oSafe.User).insert({ identifier: account.providerUserId });
294
294
  account.userId = user.id;
295
295
  }
296
296
  await invalidateSession(account.userId);
297
297
  // update elements
298
- account.hashPassword = oSafe.password.passwordHash(password);
298
+ account.hashPassword = await oSafe.password.hash(password);
299
299
  account.token = undefined;
300
300
  account.expiresAt = undefined;
301
301
  account.lastVerifiedAt = new Date();
@@ -0,0 +1,16 @@
1
+ import { type Handle } from '@sveltejs/kit';
2
+ export type RouteGuardConfig = {
3
+ anonymous?: string[];
4
+ authenticated: string[];
5
+ redirectToLogin: string;
6
+ redirectAuthenticated: string;
7
+ /**
8
+ * We need this import
9
+ *
10
+ * `import { redirect } from '@sveltejs/kit'` */
11
+ redirect: (status: number, url: string) => void;
12
+ };
13
+ /**
14
+ * Creates a handle function with the provided route guard configuration
15
+ */
16
+ export declare function handleGuard(config: RouteGuardConfig): Handle;
@@ -0,0 +1,67 @@
1
+ import {} from '@sveltejs/kit';
2
+ import { remult } from 'remult';
3
+ /**
4
+ * Checks if a path matches a pattern that may include wildcards
5
+ * @param path The actual path to check
6
+ * @param pattern The pattern that may include wildcards (*)
7
+ */
8
+ function pathMatchesPattern(path, pattern) {
9
+ // Convert the pattern to a regex
10
+ const regexPattern = pattern.replace(/\//g, '\\/').replace(/\*/g, '.*');
11
+ const regex = new RegExp(`^${regexPattern}$`);
12
+ return regex.test(path);
13
+ }
14
+ /**
15
+ * Checks if a path matches any of the patterns in the array
16
+ */
17
+ function pathMatchesAnyPattern(path, patterns) {
18
+ return patterns.some((pattern) => pathMatchesPattern(path, pattern));
19
+ }
20
+ /**
21
+ * Creates a handle function with the provided route guard configuration
22
+ */
23
+ export function handleGuard(config) {
24
+ return async ({ event, resolve }) => {
25
+ const path = event.url.pathname;
26
+ const fullUrl = event.url.pathname + event.url.search;
27
+ const isAuthenticated = !!remult.user;
28
+ // Check if the path is in the anonymous routes
29
+ const isAnonymousRoute = config.anonymous ? pathMatchesAnyPattern(path, config.anonymous) : false;
30
+ // Check if the path is in the authenticated routes
31
+ const isAuthenticatedRoute = pathMatchesAnyPattern(path, config.authenticated);
32
+ // Check if the current path is the login page
33
+ const isLoginPage = path === config.redirectToLogin || path === config.redirectToLogin.replace(/\/$/, '');
34
+ // Create login URL with redirect parameter
35
+ const createLoginUrl = (returnUrl) => {
36
+ const encodedReturnUrl = encodeURIComponent(returnUrl);
37
+ const separator = config.redirectToLogin.includes('?') ? '&' : '?';
38
+ return `${config.redirectToLogin}${separator}redirect=${encodedReturnUrl}`;
39
+ };
40
+ // Handle root path
41
+ if (path === config.redirectToLogin) {
42
+ if (isAuthenticated) {
43
+ config.redirect(302, config.redirectAuthenticated);
44
+ }
45
+ else {
46
+ // Only redirect if we're not already on the login page
47
+ if (!isLoginPage) {
48
+ config.redirect(302, config.redirectToLogin);
49
+ }
50
+ }
51
+ }
52
+ // If user is not authenticated and tries to access an authenticated route
53
+ if (!isAuthenticated && isAuthenticatedRoute) {
54
+ // Redirect to login with the current URL as the redirect target
55
+ // Only redirect if we're not already on the login page
56
+ if (!isLoginPage) {
57
+ config.redirect(302, createLoginUrl(fullUrl));
58
+ }
59
+ }
60
+ // If user is authenticated and tries to access an anonymous-only route
61
+ // Only check if anonymous routes are defined
62
+ if (config.anonymous && isAuthenticated && isAnonymousRoute) {
63
+ config.redirect(302, config.redirectAuthenticated);
64
+ }
65
+ return resolve(event);
66
+ };
67
+ }
@@ -1,5 +1,7 @@
1
1
  import * as arctic from 'arctic';
2
+ import { handleAuth } from './handleAuth.js';
3
+ import { handleGuard } from './handleGuard.js';
2
4
  export { auth, authModuleRaw } from './module';
3
5
  export { checkOAuthConfig } from './providers/helperProvider';
4
6
  export { github } from './providers/github';
5
- export { arctic };
7
+ export { arctic, handleAuth, handleGuard };
@@ -1,5 +1,7 @@
1
1
  import * as arctic from 'arctic';
2
+ import { handleAuth } from './handleAuth.js';
3
+ import { handleGuard } from './handleGuard.js';
2
4
  export { auth, authModuleRaw } from './module';
3
5
  export { checkOAuthConfig } from './providers/helperProvider';
4
6
  export { github } from './providers/github';
5
- export { arctic };
7
+ export { arctic, handleAuth, handleGuard };
@@ -28,6 +28,11 @@ type AuthOptions<TUserEntity extends FFAuthUser = FFAuthUser, TSessionEntity ext
28
28
  };
29
29
  debug?: boolean;
30
30
  ui?: false | RecursivePartial<firstlyDataAuth['ui']>;
31
+ strings?: {
32
+ resetPasswordSend?: string;
33
+ anErrorOccurred?: string;
34
+ cannotSignUp?: string;
35
+ };
31
36
  /** Usefull to overwrite where the static files are */
32
37
  uiStaticPath?: string;
33
38
  session?: {
@@ -63,52 +68,55 @@ type AuthOptions<TUserEntity extends FFAuthUser = FFAuthUser, TSessionEntity ext
63
68
  roles?: string[];
64
69
  }[];
65
70
  password?: {
66
- /**
67
- * Reseting the password
68
- */
69
- resetPasswordSend?: (args: {
70
- email: string;
71
- url: string;
72
- }) => Promise<void>;
73
- /** in secondes @default 5 minutes */
74
- resetPasswordExpiresIn?: number;
75
- /**
76
- * Verify the Mail
77
- */
78
- verifyMailSend?: (args: {
79
- email: string;
80
- url: string;
81
- }) => Promise<void>;
82
- /** in secondes @default 5 minutes */
83
- verifyMailExpiresIn?: number;
84
- settings?: {
71
+ mail?: {
72
+ reset?: {
73
+ send?: (args: {
74
+ email: string;
75
+ url: string;
76
+ }) => Promise<void>;
77
+ /** in secondes @default 5 minutes */
78
+ expiresIn?: number;
79
+ };
80
+ verify?: {
81
+ send?: (args: {
82
+ email: string;
83
+ url: string;
84
+ }) => Promise<void>;
85
+ /** in secondes @default 5 minutes */
86
+ expiresIn?: number;
87
+ };
88
+ };
89
+ algo?: {
90
+ /**
91
+ * Validate the password or throw an error.
92
+ *
93
+ * Here is an example (and it's the default implementation):
94
+ * ```
95
+ * function validatePassword(password: string) {
96
+ * if (typeof password !== 'string' || password.length < 6 || password.length > 255) {
97
+ * throw new EntityError({ message: 'Invalid password' })
98
+ * }
99
+ * }
100
+ * ```
101
+ */
102
+ validateInput?: ({ identifier, password }: {
103
+ identifier: string;
104
+ password: string;
105
+ }) => void;
106
+ /**
107
+ * If you want to NOT use the default bcrypt, you can pass your own thing!
108
+ */
109
+ hash?: (password: string) => Promise<string>;
110
+ /**
111
+ * If you want to NOT use the default bcrypt, you can pass your own thing!
112
+ */
113
+ verify?: (password: string, hash: string) => Promise<boolean>;
85
114
  bcrypt?: {
86
- /**
87
- * Validate the password or throw an error.
88
- *
89
- * Here is an example (and it's the default implementation):
90
- * ```
91
- * function validatePassword(password: string) {
92
- * if (typeof password !== 'string' || password.length < 6 || password.length > 255) {
93
- * throw new EntityError({ message: 'Invalid password' })
94
- * }
95
- * }
96
- * ```
97
- */
98
- validatePassword?: (password: string) => void;
99
- /**
100
- * If you want to NOT use the default bcrypt, you can pass your own thing!
101
- */
102
- passwordHash?: (password: string) => string;
103
115
  /**
104
116
  * The number of rounds to use for the bcrypt hash.
105
117
  * @default 10
106
118
  */
107
119
  saltRounds?: number;
108
- /**
109
- * If you want to NOT use the default bcrypt, you can pass your own thing!
110
- */
111
- passwordVerify?: (password: string, hash: string) => boolean;
112
120
  };
113
121
  };
114
122
  };
@@ -135,9 +143,12 @@ export declare const getSafeOptions: <TUserEntity extends FFAuthUser = FFAuthUse
135
143
  signUp: boolean;
136
144
  password: {
137
145
  enabled: boolean;
138
- validatePassword: (password: string) => void;
139
- passwordHash: (password: string) => string;
140
- passwordVerify: (password: string, hash: string) => boolean;
146
+ validateInput: ({ identifier, password }: {
147
+ identifier: string;
148
+ password: string;
149
+ }) => void;
150
+ hash: ((password: string) => Promise<string>) | ((password: string) => string);
151
+ verify: ((password: string, hash: string) => Promise<boolean>) | ((password: string, hash: string) => boolean);
141
152
  };
142
153
  otp: {
143
154
  enabled: boolean;
@@ -157,52 +168,55 @@ export declare const getSafeOptions: <TUserEntity extends FFAuthUser = FFAuthUse
157
168
  roles?: string[];
158
169
  }[];
159
170
  password?: {
160
- /**
161
- * Reseting the password
162
- */
163
- resetPasswordSend?: (args: {
164
- email: string;
165
- url: string;
166
- }) => Promise<void>;
167
- /** in secondes @default 5 minutes */
168
- resetPasswordExpiresIn?: number;
169
- /**
170
- * Verify the Mail
171
- */
172
- verifyMailSend?: (args: {
173
- email: string;
174
- url: string;
175
- }) => Promise<void>;
176
- /** in secondes @default 5 minutes */
177
- verifyMailExpiresIn?: number;
178
- settings?: {
171
+ mail?: {
172
+ reset?: {
173
+ send?: (args: {
174
+ email: string;
175
+ url: string;
176
+ }) => Promise<void>;
177
+ /** in secondes @default 5 minutes */
178
+ expiresIn?: number;
179
+ };
180
+ verify?: {
181
+ send?: (args: {
182
+ email: string;
183
+ url: string;
184
+ }) => Promise<void>;
185
+ /** in secondes @default 5 minutes */
186
+ expiresIn?: number;
187
+ };
188
+ };
189
+ algo?: {
190
+ /**
191
+ * Validate the password or throw an error.
192
+ *
193
+ * Here is an example (and it's the default implementation):
194
+ * ```
195
+ * function validatePassword(password: string) {
196
+ * if (typeof password !== 'string' || password.length < 6 || password.length > 255) {
197
+ * throw new EntityError({ message: 'Invalid password' })
198
+ * }
199
+ * }
200
+ * ```
201
+ */
202
+ validateInput?: ({ identifier, password }: {
203
+ identifier: string;
204
+ password: string;
205
+ }) => void;
206
+ /**
207
+ * If you want to NOT use the default bcrypt, you can pass your own thing!
208
+ */
209
+ hash?: (password: string) => Promise<string>;
210
+ /**
211
+ * If you want to NOT use the default bcrypt, you can pass your own thing!
212
+ */
213
+ verify?: (password: string, hash: string) => Promise<boolean>;
179
214
  bcrypt?: {
180
- /**
181
- * Validate the password or throw an error.
182
- *
183
- * Here is an example (and it's the default implementation):
184
- * ```
185
- * function validatePassword(password: string) {
186
- * if (typeof password !== 'string' || password.length < 6 || password.length > 255) {
187
- * throw new EntityError({ message: 'Invalid password' })
188
- * }
189
- * }
190
- * ```
191
- */
192
- validatePassword?: (password: string) => void;
193
- /**
194
- * If you want to NOT use the default bcrypt, you can pass your own thing!
195
- */
196
- passwordHash?: (password: string) => string;
197
215
  /**
198
216
  * The number of rounds to use for the bcrypt hash.
199
217
  * @default 10
200
218
  */
201
219
  saltRounds?: number;
202
- /**
203
- * If you want to NOT use the default bcrypt, you can pass your own thing!
204
- */
205
- passwordVerify?: (password: string, hash: string) => boolean;
206
220
  };
207
221
  };
208
222
  };
@@ -220,6 +234,11 @@ export declare const getSafeOptions: <TUserEntity extends FFAuthUser = FFAuthUse
220
234
  };
221
235
  oAuths?: FFOAuth2Provider[];
222
236
  } | undefined;
237
+ strings: {
238
+ resetPasswordSend: string;
239
+ anErrorOccurred: string;
240
+ cannotSignUp: string;
241
+ };
223
242
  };
224
243
  export declare const authModuleRaw: Module;
225
244
  /**