firstly 0.0.7 → 0.0.9

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 (70) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/esm/BaseEnum.d.ts +2 -13
  3. package/esm/BaseEnum.js +0 -4
  4. package/esm/FF_Entity.js +20 -4
  5. package/esm/SqlDatabase/FF_LogToConsole.d.ts +4 -1
  6. package/esm/SqlDatabase/FF_LogToConsole.js +15 -8
  7. package/esm/api/index.d.ts +4 -4
  8. package/esm/api/index.js +13 -13
  9. package/esm/auth/Adapter.js +1 -9
  10. package/esm/auth/AuthController.server.d.ts +1 -2
  11. package/esm/auth/AuthController.server.js +21 -12
  12. package/esm/auth/RoleHelpers.d.ts +2 -2
  13. package/esm/auth/RoleHelpers.js +6 -4
  14. package/esm/auth/client/Auth.d.ts +11 -4
  15. package/esm/auth/client/Auth.js +14 -6
  16. package/esm/auth/{Entities.d.ts → client/Entities.d.ts} +4 -4
  17. package/esm/auth/{Entities.js → client/Entities.js} +33 -17
  18. package/esm/auth/client/index.d.ts +5 -0
  19. package/esm/auth/client/index.js +5 -0
  20. package/esm/auth/helper.d.ts +6 -1
  21. package/esm/auth/helper.js +11 -4
  22. package/esm/auth/index.d.ts +11 -11
  23. package/esm/auth/index.js +93 -78
  24. package/esm/auth/providers/github.js +2 -1
  25. package/esm/auth/providers/index.js +1 -1
  26. package/esm/auth/providers/strava.js +2 -1
  27. package/esm/auth/static/assets/{Page-RIbXHuZG.d.ts → Page-BEFYPjis.d.ts} +1 -1
  28. package/esm/auth/static/assets/{Page-RIbXHuZG.js → Page-BEFYPjis.js} +1 -1
  29. package/esm/auth/static/assets/Page-Cfysx_UV.d.ts +6 -0
  30. package/esm/auth/static/assets/Page-Cfysx_UV.js +18 -0
  31. package/esm/auth/static/assets/{Page-DBWJjlEQ.d.ts → Page-DtgkOCJs.d.ts} +1 -1
  32. package/esm/auth/static/assets/{Page-DBWJjlEQ.js → Page-DtgkOCJs.js} +1 -1
  33. package/esm/auth/static/assets/index-QypqCYwC.d.ts +63 -0
  34. package/esm/auth/static/assets/index-QypqCYwC.js +2 -0
  35. package/esm/auth/static/index.html +1 -1
  36. package/esm/auth/types.d.ts +7 -5
  37. package/esm/bin/cmd.js +28 -14
  38. package/esm/cellsBuildor.d.ts +5 -4
  39. package/esm/cellsBuildor.js +42 -17
  40. package/esm/changeLog/index.d.ts +23 -7
  41. package/esm/changeLog/index.js +24 -18
  42. package/esm/feedback/FeedbackController.d.ts +12 -3
  43. package/esm/feedback/FeedbackController.js +62 -13
  44. package/esm/feedback/index.d.ts +1 -0
  45. package/esm/feedback/ui/DialogIssue.svelte +26 -7
  46. package/esm/feedback/ui/DialogIssues.svelte +7 -2
  47. package/esm/handle/index.d.ts +1 -1
  48. package/esm/helper.js +3 -2
  49. package/esm/index.d.ts +10 -3
  50. package/esm/index.js +1 -1
  51. package/esm/mail/index.js +15 -10
  52. package/esm/storeList.d.ts +3 -1
  53. package/esm/storeList.js +20 -10
  54. package/esm/ui/Field.svelte +11 -13
  55. package/esm/ui/FieldGroup.svelte +4 -2
  56. package/esm/ui/Grid.svelte +90 -20
  57. package/esm/ui/Grid.svelte.d.ts +1 -0
  58. package/esm/ui/GridPaginate.svelte +12 -10
  59. package/esm/ui/GridPaginate.svelte.d.ts +1 -1
  60. package/esm/ui/dialog/DialogPrimitive.svelte +1 -5
  61. package/esm/ui/dialog/dialog.d.ts +10 -8
  62. package/esm/ui/dialog/dialog.js +9 -10
  63. package/esm/ui/internals/Input.svelte +10 -1
  64. package/esm/ui/link/LinkPlus.svelte +41 -29
  65. package/esm/vite/index.js +4 -1
  66. package/package.json +8 -8
  67. package/esm/auth/static/assets/Page-apb_xgZT.d.ts +0 -6
  68. package/esm/auth/static/assets/Page-apb_xgZT.js +0 -18
  69. package/esm/auth/static/assets/index-qfq98Nyd.d.ts +0 -63
  70. package/esm/auth/static/assets/index-qfq98Nyd.js +0 -2
package/CHANGELOG.md CHANGED
@@ -1,5 +1,28 @@
1
1
  # firstly
2
2
 
3
+ ## 0.0.9
4
+
5
+ ### Patch Changes
6
+
7
+ - [#43](https://github.com/jycouet/firstly/pull/43)
8
+ [`46cfc39`](https://github.com/jycouet/firstly/commit/46cfc39090fc448a22c5ca95e45507a31ab8e2e0)
9
+ Thanks [@jycouet](https://github.com/jycouet)! - better enum filter, grid action left/right, bump
10
+ deps, opti session check, action after createOptionWhenNoResult
11
+
12
+ ## 0.0.8
13
+
14
+ ### Patch Changes
15
+
16
+ - [#27](https://github.com/jycouet/firstly/pull/27)
17
+ [`66711b2`](https://github.com/jycouet/firstly/commit/66711b2373c69006d7ae5f06d8f4a6cb0e43670b)
18
+ Thanks [@jycouet](https://github.com/jycouet)! - fix the session creation on signIn! (+default
19
+ expiration is 30 days)
20
+
21
+ - [#27](https://github.com/jycouet/firstly/pull/27)
22
+ [`0657c5c`](https://github.com/jycouet/firstly/commit/0657c5ca8b81673b493a6815a196a8c5351ecdf0)
23
+ Thanks [@jycouet](https://github.com/jycouet)! - add uiStaticPath option in auth module to
24
+ overwrite where are the static files for the module (dev option)
25
+
3
26
  ## 0.0.7
4
27
 
5
28
  ### Patch Changes
package/esm/BaseEnum.d.ts CHANGED
@@ -1,4 +1,3 @@
1
- import { type IdFilter } from 'remult';
2
1
  import type { FindOptionsBase, Repository } from 'remult';
3
2
  export type FF_Icon = {
4
3
  data?: string | string[];
@@ -21,24 +20,14 @@ export type BaseItem = BaseEnumOptions & {
21
20
  export type BaseEnumOptions<Entity = any> = {
22
21
  caption?: string;
23
22
  icon?: FF_Icon;
24
- where?: IdFilter<Entity> | FindOptionsBase<Entity>['where'];
23
+ where?: FindOptionsBase<Entity>['where'];
25
24
  class?: string;
26
25
  };
27
26
  export declare class BaseEnum<Entity = any> {
28
27
  id: string;
29
28
  caption?: string;
30
29
  icon?: FF_Icon;
31
- where?: IdFilter<Entity> | FindOptionsBase<Entity>['where'];
30
+ where?: FindOptionsBase<Entity>['where'];
32
31
  class?: string;
33
32
  constructor(_id: string | number, options?: BaseEnumOptions<Entity>);
34
- getWhere: () => this | Entity[] | {
35
- $ne?: Entity | Entity[] | undefined;
36
- '!='?: Entity | Entity[] | undefined;
37
- $in?: Entity[] | undefined;
38
- $nin?: Entity[] | undefined;
39
- } | {
40
- $id: import("remult").ValueFilter<Entity extends {
41
- id?: number | undefined;
42
- } ? number : string>;
43
- } | import("remult").EntityFilter<Entity> | NonNullable<Entity>;
44
33
  }
package/esm/BaseEnum.js CHANGED
@@ -1,4 +1,3 @@
1
- import {} from 'remult';
2
1
  export class BaseEnum {
3
2
  id;
4
3
  caption;
@@ -15,7 +14,4 @@ export class BaseEnum {
15
14
  options.icon.caption = options?.caption;
16
15
  }
17
16
  }
18
- getWhere = () => {
19
- return this.where ? this.where : this;
20
- };
21
17
  }
package/esm/FF_Entity.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { Entity } from 'remult';
2
+ import { recordDeleted, recordSaved } from './changeLog';
2
3
  const toAllow = (permission) => {
3
4
  if (permission) {
4
5
  if (Array.isArray(permission)) {
@@ -16,9 +17,24 @@ export function FF_Entity(key, options) {
16
17
  allowApiInsert: options.allowApiInsert ?? toAllow(options.permissionApiInsert),
17
18
  allowApiRead: options.allowApiRead ?? toAllow(options.permissionApiRead),
18
19
  allowApiUpdate: options.allowApiUpdate ?? toAllow(options.permissionApiUpdate),
19
- // saved: async (item, e) => {
20
- // console.log('was saved')
21
- // await options?.saved?.(item, e)
22
- // },
20
+ // changesLogs
21
+ saved: async (entity, e) => {
22
+ await options?.saved?.(entity, e);
23
+ if (options.changeLog === false) {
24
+ // Don't log changes
25
+ }
26
+ else {
27
+ await recordSaved(entity, e, options.changeLog);
28
+ }
29
+ },
30
+ deleted: async (entity, e) => {
31
+ await options?.deleted?.(entity, e);
32
+ if (options.changeLog === false) {
33
+ // Don't log changes
34
+ }
35
+ else {
36
+ await recordDeleted(entity, e, options.changeLog);
37
+ }
38
+ },
23
39
  });
24
40
  }
@@ -1 +1,4 @@
1
- export declare const FF_LogToConsole: (duration: number, query: string, args: Record<string, any>, short?: boolean) => string | undefined;
1
+ export declare const FF_LogToConsole: (duration: number, query: string, args: Record<string, any>, options?: {
2
+ withDetails?: boolean;
3
+ tablesToHide?: string[][];
4
+ }) => string | undefined;
@@ -16,7 +16,7 @@ const typeQuery = new Map([
16
16
  ]);
17
17
  const keys = ['FROM', 'WHERE', 'LIMIT', 'OFFSET'];
18
18
  const typeQueryKey = Array.from(typeQuery.keys());
19
- export const FF_LogToConsole = (duration, query, args, short = true) => {
19
+ export const FF_LogToConsole = (duration, query, args, options) => {
20
20
  const rawSql = query
21
21
  .replace(/(\r\n|\n|\r|\t)/gm, ' ')
22
22
  .replace(/ +/g, ' ')
@@ -79,7 +79,10 @@ export const FF_LogToConsole = (duration, query, args, short = true) => {
79
79
  const subTables = uniqueTables.slice(0, -1);
80
80
  const time = ` ${bgCyan((duration * 1000).toFixed(0).padStart(3) + ' ms ')}`;
81
81
  let toLog = '';
82
- if (short) {
82
+ if (options?.withDetails) {
83
+ toLog = `${typeQuery.get(first) || '💢'}` + time + ` ${final_s}`;
84
+ }
85
+ else {
83
86
  toLog =
84
87
  `${typeQuery.get(first) || '💢'}` +
85
88
  `${time}` +
@@ -87,12 +90,16 @@ export const FF_LogToConsole = (duration, query, args, short = true) => {
87
90
  `${listArgs.length > 0 ? ` { ${listArgs.join(', ')} }` : ``}` +
88
91
  `${subTables.length > 0 ? magenta(` (sub: ${subTables.join(', ')})`) : ``}`;
89
92
  }
90
- else {
91
- toLog = `${typeQuery.get(first) || '💢'}` + time + ` ${final_s}`;
92
- }
93
- // Filter out a few things
94
- const filterOutTable = ['"auth_user"', '"auth_user_session"'];
95
- const OnoOfFiltered = tables.length === 1 && filterOutTable.includes(tables[0]);
93
+ const toFilterOut = options?.tablesToHide ?? [
94
+ ['__remult_migrations_version'],
95
+ ['information_Schema.tables'],
96
+ ['information_schema.columns'],
97
+ ['ff_auth.accounts'],
98
+ ['ff_auth.users'],
99
+ ['ff_auth.users_sessions'],
100
+ ['_ff_change_logs'],
101
+ ];
102
+ const OnoOfFiltered = toFilterOut.some((item) => item.every((i) => tables.map((c) => c.replaceAll('"', '')).includes(i)));
96
103
  if (!OnoOfFiltered) {
97
104
  // console.log(`toLogLong`, toLogLong)
98
105
  log.info(toLog);
@@ -1,5 +1,5 @@
1
- /// <reference types=".pnpm/@sveltejs+kit@2.5.24_@sveltejs+vite-plugin-svelte@3.1.1_svelte@4.2.18_vite@5.4.1_@types+node@_vtylvkjv5lewhfcl4vq2py4rce/node_modules/@sveltejs/kit" />
2
- import { type Handle, type MaybePromise, type RequestEvent } from '@sveltejs/kit';
1
+ /// <reference types=".pnpm/@sveltejs+kit@2.5.24_@sveltejs+vite-plugin-svelte@3.1.2_svelte@4.2.18_vite@5.4.1_@types+node@_lnml5jetshdinsnlj53joqxhde/node_modules/@sveltejs/kit" />
2
+ import type { Handle, RequestEvent } from '@sveltejs/kit';
3
3
  import { type ClassType } from 'remult';
4
4
  import type { RemultServerOptions } from 'remult/server';
5
5
  import { type MailOptions } from '../mail';
@@ -15,9 +15,9 @@ export type Module = {
15
15
  initRequest?: RemultServerOptions<RequestEvent>['initRequest'];
16
16
  handlePreRemult?: Handle;
17
17
  handlePosRemult?: Handle;
18
- earlyReturn?: (input: Parameters<Handle>[0]) => MaybePromise<{
18
+ earlyReturn?: (input: Parameters<Handle>[0]) => Promise<{
19
19
  early: false;
20
- resolve?: never;
20
+ resolve?: undefined;
21
21
  } | {
22
22
  early: true;
23
23
  resolve: ReturnType<Handle>;
package/esm/api/index.js CHANGED
@@ -1,4 +1,3 @@
1
- import {} from '@sveltejs/kit';
2
1
  import nodemailer from 'nodemailer';
3
2
  import { remult } from 'remult';
4
3
  import { remultSveltekit } from 'remult/remult-sveltekit';
@@ -23,9 +22,10 @@ export const firstly = (o) => {
23
22
  error: o.error
24
23
  ? o.error
25
24
  : async (e) => {
26
- // if 500 we move to 501 to avoid the default retry mechanism
27
- if (e.httpStatusCode == 500) {
28
- e.sendError(501, e.responseBody);
25
+ // REMULT P2: validation error should probably be 409
26
+ // if 400 we move to 409
27
+ if (e.httpStatusCode == 400) {
28
+ e.sendError(409, e.responseBody);
29
29
  }
30
30
  },
31
31
  // Add user configuration
@@ -36,6 +36,15 @@ export const firstly = (o) => {
36
36
  initRequest: async (kitEvent, op) => {
37
37
  // usefull for later...
38
38
  remult.context.url = kitEvent.url;
39
+ remult.context.setHeaders = (headers) => {
40
+ kitEvent.setHeaders(headers);
41
+ };
42
+ remult.context.setCookie = (name, value, opts) => {
43
+ kitEvent.cookies.set(name, value, opts);
44
+ };
45
+ remult.context.deleteCookie = (name, opts) => {
46
+ kitEvent.cookies.delete(name, opts);
47
+ };
39
48
  for (let i = 0; i < modulesSorted.length; i++) {
40
49
  const f = modulesSorted[i].initRequest;
41
50
  if (f) {
@@ -48,15 +57,6 @@ export const firstly = (o) => {
48
57
  }
49
58
  }
50
59
  }
51
- remult.context.setHeaders = (headers) => {
52
- kitEvent.setHeaders(headers);
53
- };
54
- remult.context.setCookie = (name, value, opts) => {
55
- kitEvent.cookies.set(name, value, opts);
56
- };
57
- remult.context.deleteCookie = (name, opts) => {
58
- kitEvent.cookies.delete(name, opts);
59
- };
60
60
  },
61
61
  initApi: async (r) => {
62
62
  if (!building) {
@@ -7,17 +7,9 @@ export class RemultLuciaAdapter {
7
7
  if (session) {
8
8
  const user = await remult.repo(oSafe.User).findId(session.userId);
9
9
  if (user) {
10
- const { identifier, ...userInfo } = user;
11
10
  return [
12
11
  { ...session, attributes: {} },
13
- {
14
- ...userInfo,
15
- attributes: {
16
- ...userInfo,
17
- name: identifier,
18
- session: { id: session.id, expiresAt: session.expiresAt },
19
- },
20
- },
12
+ { ...user, attributes: oSafe.transformDbUserToClientUser(session, user) },
21
13
  ];
22
14
  }
23
15
  }
@@ -10,8 +10,7 @@ export declare class AuthControllerServer {
10
10
  */
11
11
  static signInDemo(name: string): Promise<string>;
12
12
  /**
13
- * This is for login / password authentication SignUp
14
- * _(The first param `name` can be "anything")_
13
+ * This is for login / password authentication invite
15
14
  */
16
15
  static invite(email: string): Promise<"Mail sent !" | "Demo Mail sent !" | "ok">;
17
16
  /**
@@ -4,10 +4,11 @@ import { generateId } from 'lucia';
4
4
  import { createDate, TimeSpan } from 'oslo';
5
5
  import { remult } from 'remult';
6
6
  import { green, magenta, yellow } from '@kitql/helpers';
7
- import { AUTH_OPTIONS, getSafeOptions, logAuth, lucia } from '.';
7
+ import { AUTH_OPTIONS, getSafeOptions, lucia } from '.';
8
8
  import { sendMail } from '../mail';
9
- import { FFAuthProvider } from './Entities.js';
10
- import { createSession } from './helper';
9
+ import { logAuth } from './client';
10
+ import { FFAuthProvider } from './client/Entities.js';
11
+ import { createOrExtendSession } from './helper';
11
12
  import { mergeRoles } from './RoleHelpers';
12
13
  async function getArgon() {
13
14
  const { Argon2id } = await import('oslo/password');
@@ -66,12 +67,11 @@ export class AuthControllerServer {
66
67
  const r = mergeRoles(user.roles, account.roles);
67
68
  user.roles = r.roles;
68
69
  await remult.repo(oSafe.User).save(user);
69
- await createSession(user.id);
70
+ await createOrExtendSession(user.id);
70
71
  return "You're in with demo account!";
71
72
  }
72
73
  /**
73
- * This is for login / password authentication SignUp
74
- * _(The first param `name` can be "anything")_
74
+ * This is for login / password authentication invite
75
75
  */
76
76
  static async invite(email) {
77
77
  const oSafe = getSafeOptions();
@@ -86,16 +86,21 @@ export class AuthControllerServer {
86
86
  }
87
87
  else {
88
88
  const token = generateId(40);
89
+ // TODO: Do we create the user or just the account ?!
90
+ // TODO 2: Invite is by mail... But the invitee can log with another provider... So what do we do?! maybe not checking the provider... and updating?
91
+ // const user = await remult.repo(oSafe.User).insert({
92
+ // identifier: email,
93
+ // })
89
94
  await remult.repo(oSafe.Account).insert({
90
95
  provider: FFAuthProvider.PASSWORD.id,
91
96
  providerUserId: email,
92
97
  // userId: user.id,
93
98
  // hashPassword: await passwordHash(password),
94
- token: oSafe.verifiedMethod === 'auto' ? undefined : token,
99
+ token: token,
95
100
  expiresAt: createDate(new TimeSpan(AUTH_OPTIONS.providers?.password?.verifyMailExpiresIn ?? 5 * 60, 's')),
96
101
  lastVerifiedAt: undefined,
97
102
  });
98
- const url = `${remult.context.url.origin}${oSafe.firstlyData.props.ui?.paths.verify_email}?token=${token}`;
103
+ const url = `${remult.context.url.origin}${oSafe.firstlyData.props.ui?.paths.reset_password}?token=${token}`;
99
104
  if (AUTH_OPTIONS?.invitationSend) {
100
105
  await AUTH_OPTIONS?.invitationSend({ email, url });
101
106
  logAuth.success(`${green('[custom]')}${magenta('[invitationSend]')} (${yellow(url)})`);
@@ -173,7 +178,7 @@ export class AuthControllerServer {
173
178
  identifier: email,
174
179
  });
175
180
  if (user) {
176
- await createSession(user.id);
181
+ await createOrExtendSession(user.id);
177
182
  }
178
183
  }
179
184
  else {
@@ -223,7 +228,7 @@ export class AuthControllerServer {
223
228
  if (existingAccount) {
224
229
  const validPassword = await passwordVerify(existingAccount?.hashPassword ?? '', password ?? '');
225
230
  if (validPassword) {
226
- await createSession(existingAccount.userId);
231
+ await createOrExtendSession(existingAccount.userId);
227
232
  return 'ok';
228
233
  }
229
234
  throw Error('Incorrect username or password');
@@ -301,6 +306,10 @@ export class AuthControllerServer {
301
306
  throw new Error('token expired');
302
307
  }
303
308
  checkPassword(password);
309
+ if (account.userId === undefined) {
310
+ const user = await remult.repo(oSafe.User).insert({ identifier: account.providerUserId });
311
+ account.userId = user.id;
312
+ }
304
313
  await lucia.invalidateUserSessions(account.userId);
305
314
  // update elements
306
315
  account.hashPassword = await passwordHash(password);
@@ -308,7 +317,7 @@ export class AuthControllerServer {
308
317
  account.expiresAt = undefined;
309
318
  account.lastVerifiedAt = new Date();
310
319
  await remult.repo(oSafe.Account).save(account);
311
- await createSession(account.userId);
320
+ await createOrExtendSession(account.userId);
312
321
  return 'reseted';
313
322
  }
314
323
  /** OTP */
@@ -385,7 +394,7 @@ export class AuthControllerServer {
385
394
  account.token = undefined;
386
395
  account.expiresAt = undefined;
387
396
  await remult.repo(oSafe.Account).save(account);
388
- await createSession(account.userId);
397
+ await createOrExtendSession(account.userId);
389
398
  return 'verified';
390
399
  }
391
400
  /** OAUTH */
@@ -1,6 +1,6 @@
1
1
  import type { ClassType } from 'remult';
2
2
  import { Log } from '@kitql/helpers';
3
- import { FFAuthUser } from './Entities';
3
+ import { FFAuthUser } from './client/Entities';
4
4
  /**
5
5
  * will merge the roles and remove duplicates
6
6
  * will return a new array & a status if the array was changed
@@ -9,4 +9,4 @@ export declare const mergeRoles: (existing: string[], newOnes: string[] | undefi
9
9
  roles: string[];
10
10
  changed: boolean;
11
11
  };
12
- export declare const initRoleFromEnv: (log: Log, userEntity: ClassType<FFAuthUser>, envValue: string | undefined, role: string) => Promise<void>;
12
+ export declare const initRoleFromEnv: (log: Log, userEntity: ClassType<FFAuthUser>, envKey: string, role: string) => Promise<void>;
@@ -1,6 +1,7 @@
1
1
  import { repo } from 'remult';
2
2
  import { cyan, green, Log, yellow } from '@kitql/helpers';
3
- import { FFAuthUser } from './Entities';
3
+ import { env } from '$env/dynamic/private';
4
+ import { FFAuthUser } from './client/Entities';
4
5
  /**
5
6
  * will merge the roles and remove duplicates
6
7
  * will return a new array & a status if the array was changed
@@ -16,7 +17,8 @@ export const mergeRoles = (existing, newOnes) => {
16
17
  }
17
18
  return { roles: Array.from(result), changed };
18
19
  };
19
- export const initRoleFromEnv = async (log, userEntity, envValue, role) => {
20
+ export const initRoleFromEnv = async (log, userEntity, envKey, role) => {
21
+ const envValue = envKey ? env[envKey] : '';
20
22
  const identifiers = envValue === undefined ? [] : (envValue ?? '').split(',').map((c) => c.trim());
21
23
  for (let i = 0; i < identifiers.length; i++) {
22
24
  const identifier = identifiers[i].trim();
@@ -35,9 +37,9 @@ export const initRoleFromEnv = async (log, userEntity, envValue, role) => {
35
37
  }
36
38
  }
37
39
  if (identifiers.length > 0) {
38
- log.info(`${cyan(role)}: ${identifiers.map((c) => green(c.trim())).join(', ')} added via ${yellow(`.env`)}.`);
40
+ log.info(`${cyan(envKey)}: ${identifiers.map((c) => green(c.trim())).join(', ')} added via ${yellow(`.env`)}.`);
39
41
  }
40
42
  else {
41
- log.info(`${cyan(role)}: No users added via ${yellow(`.env`)}.`);
43
+ log.info(`${cyan(envKey)}: No users added via ${yellow(`.env`)}.`);
42
44
  }
43
45
  };
@@ -1,14 +1,24 @@
1
1
  import type { AuthorizationURLOptions } from '..';
2
2
  export declare class Auth {
3
+ /** DO NOT USE */
3
4
  static signOutFn: any;
5
+ /** DO NOT USE */
4
6
  static signInDemoFn: any;
7
+ /** DO NOT USE */
5
8
  static inviteFn: any;
9
+ /** DO NOT USE */
6
10
  static signUpPasswordFn: any;
11
+ /** DO NOT USE */
7
12
  static signInPasswordFn: any;
13
+ /** DO NOT USE */
8
14
  static forgotPasswordFn: any;
15
+ /** DO NOT USE */
9
16
  static resetPasswordFn: any;
17
+ /** DO NOT USE */
10
18
  static signInOTPFn: any;
19
+ /** DO NOT USE */
11
20
  static verifyOtpFn: any;
21
+ /** DO NOT USE */
12
22
  static signInOAuthGetUrlFn: any;
13
23
  /**
14
24
  * Sign out the current user
@@ -20,18 +30,15 @@ export declare class Auth {
20
30
  */
21
31
  static signInDemo(name: string): Promise<any>;
22
32
  /**
23
- * This is for login / password authentication SignUp
24
- * _(The first param `name` can be "anything")_
33
+ * This is for login / password authentication Invite someone
25
34
  */
26
35
  static invite(email: string): Promise<any>;
27
36
  /**
28
37
  * This is for login / password authentication SignUp
29
- * _(The first param `email` can be "anything")_
30
38
  */
31
39
  static signUpPassword(email: string, password: string): Promise<any>;
32
40
  /**
33
41
  * This is for login / password authentication SignIn
34
- * _(The first param `email` can be "anything")_
35
42
  */
36
43
  static signInPassword(email: string, password: string): Promise<any>;
37
44
  /**
@@ -4,17 +4,28 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
4
4
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
5
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6
6
  };
7
- import { BackendMethod } from 'remult';
7
+ import { Allow, BackendMethod } from 'remult';
8
8
  export class Auth {
9
+ // Do not show for firstly users ?
10
+ /** DO NOT USE */
9
11
  static signOutFn;
12
+ /** DO NOT USE */
10
13
  static signInDemoFn;
14
+ /** DO NOT USE */
11
15
  static inviteFn;
16
+ /** DO NOT USE */
12
17
  static signUpPasswordFn;
18
+ /** DO NOT USE */
13
19
  static signInPasswordFn;
20
+ /** DO NOT USE */
14
21
  static forgotPasswordFn;
22
+ /** DO NOT USE */
15
23
  static resetPasswordFn;
24
+ /** DO NOT USE */
16
25
  static signInOTPFn;
26
+ /** DO NOT USE */
17
27
  static verifyOtpFn;
28
+ /** DO NOT USE */
18
29
  static signInOAuthGetUrlFn;
19
30
  /**
20
31
  * Sign out the current user
@@ -30,22 +41,19 @@ export class Auth {
30
41
  return await Auth.signInDemoFn(name);
31
42
  }
32
43
  /**
33
- * This is for login / password authentication SignUp
34
- * _(The first param `name` can be "anything")_
44
+ * This is for login / password authentication Invite someone
35
45
  */
36
46
  static async invite(email) {
37
47
  return await Auth.inviteFn(email);
38
48
  }
39
49
  /**
40
50
  * This is for login / password authentication SignUp
41
- * _(The first param `email` can be "anything")_
42
51
  */
43
52
  static async signUpPassword(email, password) {
44
53
  return await Auth.signUpPasswordFn(email, password);
45
54
  }
46
55
  /**
47
56
  * This is for login / password authentication SignIn
48
- * _(The first param `email` can be "anything")_
49
57
  */
50
58
  static async signInPassword(email, password) {
51
59
  return await Auth.signInPasswordFn(email, password);
@@ -96,7 +104,7 @@ __decorate([
96
104
  BackendMethod({ allowed: true })
97
105
  ], Auth, "signInDemo", null);
98
106
  __decorate([
99
- BackendMethod({ allowed: true })
107
+ BackendMethod({ allowed: Allow.authenticated })
100
108
  ], Auth, "invite", null);
101
109
  __decorate([
102
110
  BackendMethod({ allowed: true })
@@ -1,7 +1,7 @@
1
- import { BaseEnum } from '../';
2
- import type { BaseEnumOptions } from '../';
3
- export declare const FF_Auth_Role: {
4
- readonly Admin: "FF_Auth_Role.Admin";
1
+ import { BaseEnum } from '../..';
2
+ import type { BaseEnumOptions } from '../..';
3
+ export declare const FF_Role_Auth: {
4
+ readonly Admin: "FF_Role_Auth.Admin";
5
5
  };
6
6
  export declare class FFAuthUser {
7
7
  id: string;
@@ -5,10 +5,10 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
5
5
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6
6
  };
7
7
  var FFAuthProvider_1;
8
- import { Entity, Fields, Relations, Validators, ValueListFieldType } from 'remult';
9
- import { BaseEnum, FF_Role } from '../';
10
- export const FF_Auth_Role = {
11
- Admin: 'FF_Auth_Role.Admin',
8
+ import { Fields, Relations, Validators, ValueListFieldType } from 'remult';
9
+ import { BaseEnum, FF_Entity, FF_Role } from '../..';
10
+ export const FF_Role_Auth = {
11
+ Admin: 'FF_Role_Auth.Admin',
12
12
  };
13
13
  let FFAuthUser = class FFAuthUser {
14
14
  id;
@@ -32,18 +32,28 @@ __decorate([
32
32
  Fields.string({
33
33
  validate: [
34
34
  Validators.unique(),
35
+ Validators.required(),
35
36
  (e) => {
36
- if (e.identifier.length < 2)
37
+ if (e.identifier?.length < 2)
37
38
  throw 'Must be at least 2 characters long';
38
39
  },
39
40
  ],
40
41
  })
41
42
  ], FFAuthUser.prototype, "identifier", void 0);
42
43
  __decorate([
43
- Fields.object({
44
+ Fields.json(() => [], {
45
+ inputType: 'selectEnum',
44
46
  valueConverter: {
45
- toDb: (x) => (x ? x.join(',') : undefined),
46
- fromDb: (x) => (x ? x.split(',') : undefined),
47
+ toDb: (x) => (x ? x.join(',') : []),
48
+ //FIXME: refacto this + remove "permissions" & add a disable user!
49
+ fromDb: (x) => {
50
+ return x
51
+ ? x
52
+ .split(',')
53
+ .map((c) => c.replace('{', '').replace('}', ''))
54
+ .filter((c) => c !== '')
55
+ : [];
56
+ },
47
57
  },
48
58
  })
49
59
  ], FFAuthUser.prototype, "roles", void 0);
@@ -54,9 +64,9 @@ __decorate([
54
64
  Relations.toMany(() => FFAuthUserSession, 'userId')
55
65
  ], FFAuthUser.prototype, "sessions", void 0);
56
66
  FFAuthUser = __decorate([
57
- Entity('ff_auth.users', {
58
- allowApiCrud: [FF_Auth_Role.Admin, FF_Role.Admin],
59
- caption: 'Auth - Users',
67
+ FF_Entity('ff_auth.users', {
68
+ allowApiCrud: [FF_Role_Auth.Admin, FF_Role.Admin],
69
+ caption: 'FF Auth - Users',
60
70
  })
61
71
  ], FFAuthUser);
62
72
  export { FFAuthUser };
@@ -107,10 +117,15 @@ __decorate([
107
117
  Fields.date({ includeInApi: false, allowNull: true })
108
118
  ], FFAuthAccount.prototype, "lastVerifiedAt", void 0);
109
119
  FFAuthAccount = __decorate([
110
- Entity('ff_auth.accounts', {
111
- allowApiCrud: [FF_Auth_Role.Admin, FF_Role.Admin],
112
- caption: 'Auth - Accounts',
120
+ FF_Entity('ff_auth.accounts', {
121
+ allowApiCrud: [FF_Role_Auth.Admin, FF_Role.Admin],
122
+ caption: 'FF Auth - Accounts',
113
123
  // id: { provider: true, userId: true },
124
+ changeLog: {
125
+ excludeColumns: (e) => {
126
+ return [e.hashPassword, e.token];
127
+ },
128
+ },
114
129
  })
115
130
  ], FFAuthAccount);
116
131
  export { FFAuthAccount };
@@ -133,9 +148,10 @@ __decorate([
133
148
  Relations.toOne(() => FFAuthUser, 'userId')
134
149
  ], FFAuthUserSession.prototype, "user", void 0);
135
150
  FFAuthUserSession = __decorate([
136
- Entity('ff_auth.users_sessions', {
137
- allowApiCrud: [FF_Auth_Role.Admin, FF_Role.Admin],
138
- caption: 'Auth - Users sessions',
151
+ FF_Entity('ff_auth.users_sessions', {
152
+ allowApiCrud: [FF_Role_Auth.Admin, FF_Role.Admin],
153
+ caption: 'FF Auth - Users sessions',
154
+ changeLog: false,
139
155
  })
140
156
  ], FFAuthUserSession);
141
157
  export { FFAuthUserSession };
@@ -1,2 +1,7 @@
1
+ import { Log } from '@kitql/helpers';
1
2
  import { Auth } from './Auth';
3
+ import { FFAuthAccount, FFAuthProvider, FFAuthUser, FFAuthUserSession } from './Entities';
4
+ export declare const logAuth: Log;
5
+ export { FF_Role_Auth } from './Entities';
2
6
  export { Auth };
7
+ export { FFAuthUser, FFAuthAccount, FFAuthProvider, FFAuthUserSession };
@@ -1,2 +1,7 @@
1
+ import { Log } from '@kitql/helpers';
1
2
  import { Auth } from './Auth';
3
+ import { FFAuthAccount, FFAuthProvider, FFAuthUser, FFAuthUserSession } from './Entities';
4
+ export const logAuth = new Log('firstly | auth');
5
+ export { FF_Role_Auth } from './Entities';
2
6
  export { Auth };
7
+ export { FFAuthUser, FFAuthAccount, FFAuthProvider, FFAuthUserSession };
@@ -1 +1,6 @@
1
- export declare function createSession(userId: string): Promise<void>;
1
+ import type { Session } from 'lucia';
2
+ /**
3
+ * Create or extend a session for a user.
4
+ * If you pass a session, it will extend it.
5
+ */
6
+ export declare function createOrExtendSession(userId: string, session?: Session): Promise<void>;