firstly 0.0.3 → 0.0.4
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.
- package/CHANGELOG.md +8 -0
- package/esm/KitFields.d.ts +3 -3
- package/esm/KitFields.js +29 -47
- package/esm/ROUTES.d.ts +4 -2
- package/esm/ROUTES.js +4 -7
- package/esm/auth/Adapter.js +10 -8
- package/esm/auth/{AuthController.d.ts → AuthController.server.d.ts} +2 -2
- package/esm/auth/{AuthController.js → AuthController.server.js} +6 -42
- package/esm/auth/README.md +13 -0
- package/esm/auth/{RoleController.d.ts → RoleHelpers.d.ts} +1 -3
- package/esm/auth/RoleHelpers.js +43 -0
- package/esm/auth/client/Auth.d.ts +69 -0
- package/esm/auth/client/Auth.js +121 -0
- package/esm/auth/client/index.d.ts +2 -0
- package/esm/auth/client/index.js +2 -0
- package/esm/auth/index.d.ts +2 -3
- package/esm/auth/index.js +27 -13
- package/esm/auth/static/assets/{Page-BwHye0GW.d.ts → Page-BYzkK4q3.d.ts} +1 -1
- package/esm/auth/static/assets/{Page-BwHye0GW.js → Page-BYzkK4q3.js} +1 -1
- package/esm/auth/static/assets/Page-ByIhtXVt.d.ts +5 -0
- package/esm/auth/static/assets/Page-ByIhtXVt.js +18 -0
- package/esm/auth/static/assets/{Page-BMOLAIFx.d.ts → Page-Do7F0Mzd.d.ts} +1 -1
- package/esm/auth/static/assets/{Page-BMOLAIFx.js → Page-Do7F0Mzd.js} +1 -1
- package/esm/auth/static/assets/index-czJ1PA1n.js +2 -0
- package/esm/auth/static/index.html +1 -1
- package/esm/bin/cmd.js +7 -6
- package/esm/formats/strings.js +0 -11
- package/esm/helper.d.ts +2 -2
- package/esm/helper.js +1 -5
- package/esm/index.d.ts +3 -2
- package/esm/index.js +8 -1
- package/esm/kitCellsBuildor.d.ts +2 -2
- package/esm/kitCellsBuildor.js +16 -6
- package/esm/kitStoreItem.js +2 -2
- package/esm/ui/Button.svelte +6 -8
- package/esm/ui/Field.svelte +9 -8
- package/esm/ui/FieldGroup.svelte +5 -3
- package/esm/ui/GridPaginate.svelte +3 -6
- package/esm/ui/Icon.svelte +6 -7
- package/esm/ui/LibIcon.js +0 -2
- package/esm/ui/dialog/DialogForm.svelte +3 -4
- package/esm/ui/dialog/dialog.d.ts +2 -0
- package/esm/ui/dialog/dialog.js +1 -0
- package/esm/ui/internals/FieldContainer.svelte +1 -1
- package/esm/ui/internals/Input.svelte +1 -1
- package/esm/ui/internals/select/MultiSelectMelt.svelte +16 -19
- package/esm/ui/internals/select/SelectMelt.svelte +10 -14
- package/esm/vite/index.js +1 -1
- package/package.json +8 -4
- package/esm/auth/RoleController.js +0 -57
- package/esm/auth/static/assets/Page-BMFREPjF.d.ts +0 -5
- package/esm/auth/static/assets/Page-BMFREPjF.js +0 -18
- package/esm/auth/static/assets/index-CKmKKRRL.js +0 -2
- /package/esm/auth/static/assets/{index-CKmKKRRL.d.ts → index-czJ1PA1n.d.ts} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# firstly
|
|
2
2
|
|
|
3
|
+
## 0.0.4
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#16](https://github.com/jycouet/firstly/pull/16)
|
|
8
|
+
[`ac00e70`](https://github.com/jycouet/firstly/commit/ac00e703af515009bbe7e078998f77ef3a9e9ce5)
|
|
9
|
+
Thanks [@jycouet](https://github.com/jycouet)! - WIP next version / split client & server imports.
|
|
10
|
+
|
|
3
11
|
## 0.0.3
|
|
4
12
|
|
|
5
13
|
### Patch Changes
|
package/esm/KitFields.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { type FieldOptions, type FieldValidator, type StringFieldOptions } from 'remult';
|
|
2
|
-
export declare function addValidator(validators: FieldOptions['validate'], newValidator: FieldOptions['validate'], atStart?: boolean): FieldValidator<
|
|
2
|
+
export declare function addValidator(validators: FieldOptions['validate'], newValidator: FieldOptions['validate'], atStart?: boolean): FieldValidator<unknown, unknown> | FieldValidator<unknown, unknown>[] | undefined;
|
|
3
3
|
export declare class KitFields {
|
|
4
|
-
static string<entityType = unknown, valueType = string>(o?: StringFieldOptions<entityType, valueType>
|
|
5
|
-
static currency<entityType =
|
|
4
|
+
static string<entityType = unknown, valueType = string>(o?: StringFieldOptions<entityType, valueType>): import("remult").ClassFieldDecorator<entityType, valueType | undefined>;
|
|
5
|
+
static currency<entityType = unknown>(o?: FieldOptions<entityType, number>): import("remult").ClassFieldDecorator<entityType, number | undefined>;
|
|
6
6
|
static dateOnly<entityType = any>(o?: FieldOptions<entityType, Date>): import("remult").ClassFieldDecorator<entityType, Date | undefined>;
|
|
7
7
|
static arrayEnum<enumType = any, entityType = any>(enumClass: enumType, o?: FieldOptions<entityType, any[]>): import("remult").ClassFieldDecorator<entityType, any[] | undefined>;
|
|
8
8
|
static arrayEnumToGql<enumType = any, entityType = any>(enumClass: enumType, o?: FieldOptions<entityType, any[]>): import("remult").ClassFieldDecorator<entityType, any[] | undefined>;
|
package/esm/KitFields.js
CHANGED
|
@@ -13,38 +13,40 @@ export function addValidator(validators, newValidator, atStart = false) {
|
|
|
13
13
|
const validatorsArray = Array.isArray(validators) ? validators : validators ? [validators] : [];
|
|
14
14
|
return atStart ? [...newValidators, ...validatorsArray] : [...validatorsArray, ...newValidators];
|
|
15
15
|
}
|
|
16
|
-
//
|
|
17
|
-
//
|
|
18
|
-
//
|
|
16
|
+
// REMULT P2: A/ Add in the doc that allowNull is false by default
|
|
17
|
+
// B/ Would be great to have a Validators.required automatically when allowNull is not true.
|
|
18
|
+
// C/ WARNING Validators.required is also checking for empty string
|
|
19
|
+
const validate_update_when_not_allow_null = (o) => {
|
|
20
|
+
const validate = [];
|
|
21
|
+
if (o.includeInApi !== false &&
|
|
22
|
+
o.serverExpression === undefined &&
|
|
23
|
+
o.sqlExpression === undefined &&
|
|
24
|
+
(o.allowNull === undefined || o.allowNull === false) &&
|
|
25
|
+
// if require: false is explicitly set, then we don't need to add required validator
|
|
26
|
+
o.required !== false) {
|
|
27
|
+
validate.push(Validators.required);
|
|
28
|
+
}
|
|
29
|
+
// let's add original validate if any
|
|
30
|
+
if (o.validate) {
|
|
31
|
+
if (Array.isArray(o.validate)) {
|
|
32
|
+
validate.push(...o.validate);
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
validate.push(o.validate);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return validate;
|
|
39
|
+
};
|
|
19
40
|
export class KitFields {
|
|
20
41
|
static string(o) {
|
|
21
|
-
// const f = Fields.string(...param)
|
|
22
|
-
// f.validate = addValidator(f.validate, Validators.required)
|
|
23
|
-
// return f
|
|
24
|
-
// empty if there is nothing coming here.
|
|
25
42
|
if (o === undefined) {
|
|
26
43
|
o = {};
|
|
27
44
|
}
|
|
28
|
-
const validate = [];
|
|
29
|
-
if (o.includeInApi !== false &&
|
|
30
|
-
(!o.allowNull || o.required) &&
|
|
31
|
-
// if require: false is explicitly set, then we don't need to add required validator
|
|
32
|
-
o.required !== false) {
|
|
33
|
-
// REMULT P2 JYC (Open an issue): to repro + issue type issue? - Probably typescript
|
|
34
|
-
// @ts-ignore
|
|
35
|
-
validate.push(Validators.required);
|
|
36
|
-
}
|
|
37
|
-
// let's add original validate if any
|
|
38
|
-
if (o.validate) {
|
|
39
|
-
if (Array.isArray(o.validate)) {
|
|
40
|
-
validate.push(...o.validate);
|
|
41
|
-
}
|
|
42
|
-
else {
|
|
43
|
-
validate.push(o.validate);
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
45
|
// let's return the field
|
|
47
|
-
return Fields.string({
|
|
46
|
+
return Fields.string({
|
|
47
|
+
...o,
|
|
48
|
+
validate: validate_update_when_not_allow_null(o),
|
|
49
|
+
});
|
|
48
50
|
}
|
|
49
51
|
static currency(o) {
|
|
50
52
|
// let's return the field
|
|
@@ -80,27 +82,9 @@ export class KitFields {
|
|
|
80
82
|
if (o === undefined) {
|
|
81
83
|
o = {};
|
|
82
84
|
}
|
|
83
|
-
const validate = [];
|
|
84
|
-
if (o.includeInApi !== false &&
|
|
85
|
-
(!o.allowNull || o.required) &&
|
|
86
|
-
// if require: false is explicitly set, then we don't need to add required validator
|
|
87
|
-
o.required !== false) {
|
|
88
|
-
// REMULT P2 JYC (Open an issue): to repro + issue type issue? - Probably typescript
|
|
89
|
-
// @ts-ignore
|
|
90
|
-
validate.push(Validators.required);
|
|
91
|
-
}
|
|
92
|
-
// let's add original validate if any
|
|
93
|
-
if (o.validate) {
|
|
94
|
-
if (Array.isArray(o.validate)) {
|
|
95
|
-
validate.push(...o.validate);
|
|
96
|
-
}
|
|
97
|
-
else {
|
|
98
|
-
validate.push(o.validate);
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
85
|
o.inputType = 'dateOnly';
|
|
102
86
|
// let's return the field
|
|
103
|
-
return Fields.dateOnly({ ...o, validate });
|
|
87
|
+
return Fields.dateOnly({ ...o, validate: validate_update_when_not_allow_null(o) });
|
|
104
88
|
}
|
|
105
89
|
static arrayEnum(enumClass, o) {
|
|
106
90
|
return Fields.json(() => Array, {
|
|
@@ -126,7 +110,6 @@ export class KitFields {
|
|
|
126
110
|
return `{${[...new Set((arr ?? []).map((c) => c.id))].join(',')}}`;
|
|
127
111
|
},
|
|
128
112
|
displayValue: (v) => {
|
|
129
|
-
// TODO to transform in enum & item one day
|
|
130
113
|
return v.map((c) => c.caption).join(', ');
|
|
131
114
|
},
|
|
132
115
|
// REMULT P2 Noam: how to do this in an official way?
|
|
@@ -152,7 +135,6 @@ export class KitFields {
|
|
|
152
135
|
return `{${[...new Set((arr ?? []).map((c) => c.id))].join(',')}}`;
|
|
153
136
|
},
|
|
154
137
|
displayValue: (v) => {
|
|
155
|
-
// TODO to transform in enum & item one day
|
|
156
138
|
return v.map((c) => c.caption).join(', ');
|
|
157
139
|
},
|
|
158
140
|
// REMULT P2 Noam: how to do this in an official way?
|
package/esm/ROUTES.d.ts
CHANGED
|
@@ -25,7 +25,7 @@ type FunctionKeys<T> = {
|
|
|
25
25
|
}[keyof T];
|
|
26
26
|
type FunctionParams<T> = T extends (...args: infer P) => any ? P : never;
|
|
27
27
|
declare const AllObjs: {
|
|
28
|
-
|
|
28
|
+
firstly_sign_in: string;
|
|
29
29
|
remult_admin: string;
|
|
30
30
|
github: (params?: {
|
|
31
31
|
owner?: (string | number);
|
|
@@ -39,6 +39,8 @@ declare const AllObjs: {
|
|
|
39
39
|
"/ui": string;
|
|
40
40
|
};
|
|
41
41
|
type AllTypes = typeof AllObjs;
|
|
42
|
+
export type Routes = keyof AllTypes extends `${string}/${infer Route}` ? `/${Route}` : keyof AllTypes;
|
|
43
|
+
export declare const routes: ("/" | "/remult" | "/remult/auth" | "/remult/enum" | "/remult/select" | "/ui" | "firstly_sign_in" | "remult_admin" | "github")[];
|
|
42
44
|
/**
|
|
43
45
|
* To be used like this:
|
|
44
46
|
* ```ts
|
|
@@ -76,7 +78,7 @@ export type KIT_ROUTES = {
|
|
|
76
78
|
SERVERS: Record<string, never>;
|
|
77
79
|
ACTIONS: Record<string, never>;
|
|
78
80
|
LINKS: {
|
|
79
|
-
'
|
|
81
|
+
'firstly_sign_in': never;
|
|
80
82
|
'remult_admin': never;
|
|
81
83
|
'github': 'owner' | 'repo';
|
|
82
84
|
};
|
package/esm/ROUTES.js
CHANGED
|
@@ -27,7 +27,7 @@ const ACTIONS = {};
|
|
|
27
27
|
* LINKS
|
|
28
28
|
*/
|
|
29
29
|
const LINKS = {
|
|
30
|
-
"
|
|
30
|
+
"firstly_sign_in": `/fly/auth/sign-in`,
|
|
31
31
|
"remult_admin": `/api/admin`,
|
|
32
32
|
"github": (params) => {
|
|
33
33
|
params = params ?? {};
|
|
@@ -80,13 +80,10 @@ export const currentSp = () => {
|
|
|
80
80
|
}
|
|
81
81
|
return record;
|
|
82
82
|
};
|
|
83
|
-
function StringOrUndefined(val) {
|
|
84
|
-
if (val === undefined) {
|
|
85
|
-
return undefined;
|
|
86
|
-
}
|
|
87
|
-
return String(val);
|
|
88
|
-
}
|
|
89
83
|
const AllObjs = { ...PAGES, ...ACTIONS, ...SERVERS, ...LINKS };
|
|
84
|
+
export const routes = [
|
|
85
|
+
...new Set(Object.keys(AllObjs).map((route) => /^\/.*|[^ ]?\/.*$/.exec(route)?.[0] ?? route)),
|
|
86
|
+
];
|
|
90
87
|
export function route(key, ...params) {
|
|
91
88
|
if (AllObjs[key] instanceof Function) {
|
|
92
89
|
const element = AllObjs[key];
|
package/esm/auth/Adapter.js
CHANGED
|
@@ -6,16 +6,18 @@ export class RemultLuciaAdapter {
|
|
|
6
6
|
const session = await remult.repo(oSafe.Session).findId(sessionId);
|
|
7
7
|
if (session) {
|
|
8
8
|
const user = await remult.repo(oSafe.User).findId(session.userId);
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
attributes: {
|
|
9
|
+
if (user) {
|
|
10
|
+
return [
|
|
11
|
+
{ ...session, attributes: {} },
|
|
12
|
+
{
|
|
14
13
|
...user,
|
|
15
|
-
|
|
14
|
+
attributes: {
|
|
15
|
+
...user,
|
|
16
|
+
session: { id: session.id, expiresAt: session.expiresAt },
|
|
17
|
+
},
|
|
16
18
|
},
|
|
17
|
-
|
|
18
|
-
|
|
19
|
+
];
|
|
20
|
+
}
|
|
19
21
|
}
|
|
20
22
|
return [null, null];
|
|
21
23
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type AuthorizationURLOptions } from '.';
|
|
2
|
-
export declare class
|
|
2
|
+
export declare class AuthControllerServer {
|
|
3
3
|
/**
|
|
4
4
|
* Sign out the current user
|
|
5
5
|
*/
|
|
@@ -45,7 +45,7 @@ export declare class AuthController {
|
|
|
45
45
|
*
|
|
46
46
|
* To be used like this for example:
|
|
47
47
|
* ```
|
|
48
|
-
* const url = await
|
|
48
|
+
* const url = await Auth.signInOAuthGetUrl('github')
|
|
49
49
|
* window.location.href = url
|
|
50
50
|
* ```
|
|
51
51
|
*
|
|
@@ -1,20 +1,14 @@
|
|
|
1
|
-
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
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
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
-
};
|
|
7
1
|
import { generateCodeVerifier, generateState } from 'arctic';
|
|
8
2
|
import { DEV } from 'esm-env';
|
|
9
3
|
import { generateId } from 'lucia';
|
|
10
4
|
import { createDate, TimeSpan } from 'oslo';
|
|
11
|
-
import {
|
|
5
|
+
import { remult } from 'remult';
|
|
12
6
|
import { green, yellow } from '@kitql/helpers';
|
|
13
7
|
import { AUTH_OPTIONS, getSafeOptions, logAuth, lucia } from '.';
|
|
14
8
|
import { sendMail } from '../mail';
|
|
15
9
|
import { AuthProvider } from './Entities.js';
|
|
16
10
|
import { createSession } from './helper';
|
|
17
|
-
import { mergeRoles } from './
|
|
11
|
+
import { mergeRoles } from './RoleHelpers';
|
|
18
12
|
async function getArgon() {
|
|
19
13
|
const { Argon2id } = await import('oslo/password');
|
|
20
14
|
return new Argon2id({
|
|
@@ -34,7 +28,7 @@ function checkPassword(password) {
|
|
|
34
28
|
throw Error('Invalid password');
|
|
35
29
|
}
|
|
36
30
|
}
|
|
37
|
-
export class
|
|
31
|
+
export class AuthControllerServer {
|
|
38
32
|
/**
|
|
39
33
|
* Sign out the current user
|
|
40
34
|
*/
|
|
@@ -174,7 +168,7 @@ export class AuthController {
|
|
|
174
168
|
.repo(oSafe.User)
|
|
175
169
|
.findOne({ where: { name: email }, include: { accounts: true } });
|
|
176
170
|
const accountPassword = existingUser?.accounts.find((c) => c.provider === AuthProvider.PASSWORD.id);
|
|
177
|
-
if (accountPassword) {
|
|
171
|
+
if (accountPassword && existingUser) {
|
|
178
172
|
const validPassword = await passwordVerify(accountPassword?.hashPassword ?? '', password ?? '');
|
|
179
173
|
if (validPassword) {
|
|
180
174
|
await createSession(existingUser.id);
|
|
@@ -312,7 +306,7 @@ export class AuthController {
|
|
|
312
306
|
}
|
|
313
307
|
const account = accounts[0];
|
|
314
308
|
const user = await remult.repo(oSafe.User).findId(account.userId);
|
|
315
|
-
if (user
|
|
309
|
+
if (user?.name !== email) {
|
|
316
310
|
throw new Error('Invalid otp.');
|
|
317
311
|
}
|
|
318
312
|
const { decodeHex } = await import('oslo/encoding');
|
|
@@ -338,7 +332,7 @@ export class AuthController {
|
|
|
338
332
|
*
|
|
339
333
|
* To be used like this for example:
|
|
340
334
|
* ```
|
|
341
|
-
* const url = await
|
|
335
|
+
* const url = await Auth.signInOAuthGetUrl('github')
|
|
342
336
|
* window.location.href = url
|
|
343
337
|
* ```
|
|
344
338
|
*
|
|
@@ -402,33 +396,3 @@ export class AuthController {
|
|
|
402
396
|
throw new Error(`${o.provider} is not configured!`);
|
|
403
397
|
}
|
|
404
398
|
}
|
|
405
|
-
__decorate([
|
|
406
|
-
BackendMethod({ allowed: true })
|
|
407
|
-
], AuthController, "signOut", null);
|
|
408
|
-
__decorate([
|
|
409
|
-
BackendMethod({ allowed: true })
|
|
410
|
-
], AuthController, "signInDemo", null);
|
|
411
|
-
__decorate([
|
|
412
|
-
BackendMethod({ allowed: false })
|
|
413
|
-
], AuthController, "invite", null);
|
|
414
|
-
__decorate([
|
|
415
|
-
BackendMethod({ allowed: true })
|
|
416
|
-
], AuthController, "signUpPassword", null);
|
|
417
|
-
__decorate([
|
|
418
|
-
BackendMethod({ allowed: true })
|
|
419
|
-
], AuthController, "signInPassword", null);
|
|
420
|
-
__decorate([
|
|
421
|
-
BackendMethod({ allowed: true })
|
|
422
|
-
], AuthController, "forgotPassword", null);
|
|
423
|
-
__decorate([
|
|
424
|
-
BackendMethod({ allowed: true })
|
|
425
|
-
], AuthController, "resetPassword", null);
|
|
426
|
-
__decorate([
|
|
427
|
-
BackendMethod({ allowed: true })
|
|
428
|
-
], AuthController, "signInOTP", null);
|
|
429
|
-
__decorate([
|
|
430
|
-
BackendMethod({ allowed: true })
|
|
431
|
-
], AuthController, "verifyOtp", null);
|
|
432
|
-
__decorate([
|
|
433
|
-
BackendMethod({ allowed: true })
|
|
434
|
-
], AuthController, "signInOAuthGetUrl", null);
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Firstly - Module - Auth
|
|
2
|
+
|
|
3
|
+
➡️ Doc available [here](https://firstly.fun/modules/auth).
|
|
4
|
+
|
|
5
|
+
## Complement
|
|
6
|
+
|
|
7
|
+
### Lucia adapter
|
|
8
|
+
|
|
9
|
+
Under the hood, we created a lucia adapter, you can check the code [here](./Adapter.ts) . Feel free
|
|
10
|
+
to copy/paste it in your own codebase. You can also suggest improvements here 😉.
|
|
11
|
+
|
|
12
|
+
By default, all tables/fields will show up in your admin and you are able to extend then with your
|
|
13
|
+
own fields.
|
|
@@ -9,6 +9,4 @@ export declare const mergeRoles: (existing: string[], newOnes: string[] | undefi
|
|
|
9
9
|
roles: string[];
|
|
10
10
|
changed: boolean;
|
|
11
11
|
};
|
|
12
|
-
export declare
|
|
13
|
-
static initRoleFromEnv: (log: Log, userEntity: ClassType<KitAuthUser>, envKey: string, role: string) => Promise<void>;
|
|
14
|
-
}
|
|
12
|
+
export declare const initRoleFromEnv: (log: Log, userEntity: ClassType<KitAuthUser>, envValue: string, role: string) => Promise<void>;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { repo } from 'remult';
|
|
2
|
+
import { cyan, green, Log, yellow } from '@kitql/helpers';
|
|
3
|
+
import { KitAuthUser } from './Entities';
|
|
4
|
+
/**
|
|
5
|
+
* will merge the roles and remove duplicates
|
|
6
|
+
* will return a new array & a status if the array was changed
|
|
7
|
+
*/
|
|
8
|
+
export const mergeRoles = (existing, newOnes) => {
|
|
9
|
+
const result = new Set(existing);
|
|
10
|
+
let changed = false;
|
|
11
|
+
for (const role of newOnes ?? []) {
|
|
12
|
+
if (!result.has(role)) {
|
|
13
|
+
result.add(role);
|
|
14
|
+
changed = true;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
return { roles: Array.from(result), changed };
|
|
18
|
+
};
|
|
19
|
+
export const initRoleFromEnv = async (log, userEntity, envValue, role) => {
|
|
20
|
+
const names = envValue === undefined ? [] : (envValue ?? '').split(',').map((c) => c.trim());
|
|
21
|
+
for (let i = 0; i < names.length; i++) {
|
|
22
|
+
const name = names[i].trim();
|
|
23
|
+
if (name !== '') {
|
|
24
|
+
let user = await repo(userEntity).findFirst({ name });
|
|
25
|
+
if (!user) {
|
|
26
|
+
user = repo(userEntity).create({ name, roles: [role] });
|
|
27
|
+
await repo(userEntity).save(user);
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
if (!user.roles.includes(role)) {
|
|
31
|
+
user.roles.push(role);
|
|
32
|
+
await repo(userEntity).save(user);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
if (names.length > 0) {
|
|
38
|
+
log.info(`${cyan(role)}: ${names.map((c) => green(c.trim())).join(', ')} added via ${yellow(`.env`)}.`);
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
log.info(`${cyan(role)}: No users added via ${yellow(`.env`)}.`);
|
|
42
|
+
}
|
|
43
|
+
};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import type { AuthorizationURLOptions } from '..';
|
|
2
|
+
export declare class Auth {
|
|
3
|
+
static signOutFn: any;
|
|
4
|
+
static signInDemoFn: any;
|
|
5
|
+
static inviteFn: any;
|
|
6
|
+
static signUpPasswordFn: any;
|
|
7
|
+
static signInPasswordFn: any;
|
|
8
|
+
static forgotPasswordFn: any;
|
|
9
|
+
static resetPasswordFn: any;
|
|
10
|
+
static signInOTPFn: any;
|
|
11
|
+
static verifyOtpFn: any;
|
|
12
|
+
static signInOAuthGetUrlFn: any;
|
|
13
|
+
/**
|
|
14
|
+
* Sign out the current user
|
|
15
|
+
*/
|
|
16
|
+
static signOut(): Promise<any>;
|
|
17
|
+
/**
|
|
18
|
+
* Sign in with a demo account
|
|
19
|
+
* _(The easiest way to demo & test your application)_
|
|
20
|
+
*/
|
|
21
|
+
static signInDemo(name: string): Promise<any>;
|
|
22
|
+
/**
|
|
23
|
+
* This is for login / password authentication SignUp
|
|
24
|
+
* _(The first param `name` can be "anything")_
|
|
25
|
+
*/
|
|
26
|
+
static invite(email: string): Promise<any>;
|
|
27
|
+
/**
|
|
28
|
+
* This is for login / password authentication SignUp
|
|
29
|
+
* _(The first param `email` can be "anything")_
|
|
30
|
+
*/
|
|
31
|
+
static signUpPassword(email: string, password: string): Promise<any>;
|
|
32
|
+
/**
|
|
33
|
+
* This is for login / password authentication SignIn
|
|
34
|
+
* _(The first param `email` can be "anything")_
|
|
35
|
+
*/
|
|
36
|
+
static signInPassword(email: string, password: string): Promise<any>;
|
|
37
|
+
/**
|
|
38
|
+
* Forgot your password ? Send a mail to reset it.
|
|
39
|
+
*/
|
|
40
|
+
static forgotPassword(email: string): Promise<any>;
|
|
41
|
+
/**
|
|
42
|
+
* Reset your password with a token
|
|
43
|
+
*/
|
|
44
|
+
static resetPassword(token: string, password: string): Promise<any>;
|
|
45
|
+
/** OTP */
|
|
46
|
+
static signInOTP(email: string): Promise<any>;
|
|
47
|
+
/**
|
|
48
|
+
* Verify the OTP code
|
|
49
|
+
*/
|
|
50
|
+
static verifyOtp(email: string, otp: string | number): Promise<any>;
|
|
51
|
+
/** OAUTH */
|
|
52
|
+
/**
|
|
53
|
+
* The the url to redirect to for the OAuth provider
|
|
54
|
+
* @param provider Has to mach one of `AUTH_OPTIONS.providers.oAuths` your configured
|
|
55
|
+
*
|
|
56
|
+
* To be used like this for example:
|
|
57
|
+
* ```
|
|
58
|
+
* const url = await Auth.signInOAuthGetUrl('github')
|
|
59
|
+
* window.location.href = url
|
|
60
|
+
* ```
|
|
61
|
+
*
|
|
62
|
+
* _(popup example should work too, and a nice example/componant would be appreciated)_
|
|
63
|
+
*/
|
|
64
|
+
static signInOAuthGetUrl<T extends keyof AuthorizationURLOptions>(o: {
|
|
65
|
+
provider: T;
|
|
66
|
+
options?: AuthorizationURLOptions[T];
|
|
67
|
+
redirect?: string;
|
|
68
|
+
}): Promise<any>;
|
|
69
|
+
}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
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
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import { BackendMethod } from 'remult';
|
|
8
|
+
export class Auth {
|
|
9
|
+
static signOutFn;
|
|
10
|
+
static signInDemoFn;
|
|
11
|
+
static inviteFn;
|
|
12
|
+
static signUpPasswordFn;
|
|
13
|
+
static signInPasswordFn;
|
|
14
|
+
static forgotPasswordFn;
|
|
15
|
+
static resetPasswordFn;
|
|
16
|
+
static signInOTPFn;
|
|
17
|
+
static verifyOtpFn;
|
|
18
|
+
static signInOAuthGetUrlFn;
|
|
19
|
+
/**
|
|
20
|
+
* Sign out the current user
|
|
21
|
+
*/
|
|
22
|
+
static async signOut() {
|
|
23
|
+
return await Auth.signOutFn();
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Sign in with a demo account
|
|
27
|
+
* _(The easiest way to demo & test your application)_
|
|
28
|
+
*/
|
|
29
|
+
static async signInDemo(name) {
|
|
30
|
+
return await Auth.signInDemoFn(name);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* This is for login / password authentication SignUp
|
|
34
|
+
* _(The first param `name` can be "anything")_
|
|
35
|
+
*/
|
|
36
|
+
static async invite(email) {
|
|
37
|
+
return await Auth.inviteFn(email);
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* This is for login / password authentication SignUp
|
|
41
|
+
* _(The first param `email` can be "anything")_
|
|
42
|
+
*/
|
|
43
|
+
static async signUpPassword(email, password) {
|
|
44
|
+
return await Auth.signUpPasswordFn(email, password);
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* This is for login / password authentication SignIn
|
|
48
|
+
* _(The first param `email` can be "anything")_
|
|
49
|
+
*/
|
|
50
|
+
static async signInPassword(email, password) {
|
|
51
|
+
return await Auth.signInPasswordFn(email, password);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Forgot your password ? Send a mail to reset it.
|
|
55
|
+
*/
|
|
56
|
+
static async forgotPassword(email) {
|
|
57
|
+
return await Auth.forgotPasswordFn(email);
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Reset your password with a token
|
|
61
|
+
*/
|
|
62
|
+
static async resetPassword(token, password) {
|
|
63
|
+
return await Auth.resetPasswordFn(token, password);
|
|
64
|
+
}
|
|
65
|
+
/** OTP */
|
|
66
|
+
static async signInOTP(email) {
|
|
67
|
+
return await Auth.signInOTPFn(email);
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Verify the OTP code
|
|
71
|
+
*/
|
|
72
|
+
static async verifyOtp(email, otp) {
|
|
73
|
+
return await Auth.verifyOtpFn(email, otp);
|
|
74
|
+
}
|
|
75
|
+
/** OAUTH */
|
|
76
|
+
/**
|
|
77
|
+
* The the url to redirect to for the OAuth provider
|
|
78
|
+
* @param provider Has to mach one of `AUTH_OPTIONS.providers.oAuths` your configured
|
|
79
|
+
*
|
|
80
|
+
* To be used like this for example:
|
|
81
|
+
* ```
|
|
82
|
+
* const url = await Auth.signInOAuthGetUrl('github')
|
|
83
|
+
* window.location.href = url
|
|
84
|
+
* ```
|
|
85
|
+
*
|
|
86
|
+
* _(popup example should work too, and a nice example/componant would be appreciated)_
|
|
87
|
+
*/
|
|
88
|
+
static async signInOAuthGetUrl(o) {
|
|
89
|
+
return await Auth.signInOAuthGetUrlFn(o.provider, o.options, o.redirect);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
__decorate([
|
|
93
|
+
BackendMethod({ allowed: true })
|
|
94
|
+
], Auth, "signOut", null);
|
|
95
|
+
__decorate([
|
|
96
|
+
BackendMethod({ allowed: true })
|
|
97
|
+
], Auth, "signInDemo", null);
|
|
98
|
+
__decorate([
|
|
99
|
+
BackendMethod({ allowed: false })
|
|
100
|
+
], Auth, "invite", null);
|
|
101
|
+
__decorate([
|
|
102
|
+
BackendMethod({ allowed: true })
|
|
103
|
+
], Auth, "signUpPassword", null);
|
|
104
|
+
__decorate([
|
|
105
|
+
BackendMethod({ allowed: true })
|
|
106
|
+
], Auth, "signInPassword", null);
|
|
107
|
+
__decorate([
|
|
108
|
+
BackendMethod({ allowed: true })
|
|
109
|
+
], Auth, "forgotPassword", null);
|
|
110
|
+
__decorate([
|
|
111
|
+
BackendMethod({ allowed: true })
|
|
112
|
+
], Auth, "resetPassword", null);
|
|
113
|
+
__decorate([
|
|
114
|
+
BackendMethod({ allowed: true })
|
|
115
|
+
], Auth, "signInOTP", null);
|
|
116
|
+
__decorate([
|
|
117
|
+
BackendMethod({ allowed: true })
|
|
118
|
+
], Auth, "verifyOtp", null);
|
|
119
|
+
__decorate([
|
|
120
|
+
BackendMethod({ allowed: true })
|
|
121
|
+
], Auth, "signInOAuthGetUrl", null);
|
package/esm/auth/index.d.ts
CHANGED
|
@@ -4,11 +4,10 @@ import type { ClassType, UserInfo } from 'remult';
|
|
|
4
4
|
import { Log } from '@kitql/helpers';
|
|
5
5
|
import type { Module } from '../api';
|
|
6
6
|
import type { ResolvedType } from '../utils/types';
|
|
7
|
-
import { KitAuthAccount, KitAuthUser, KitAuthUserSession } from './Entities';
|
|
7
|
+
import { AuthProvider, KitAuthAccount, KitAuthUser, KitAuthUserSession } from './Entities';
|
|
8
8
|
import type { firstlyData } from './types';
|
|
9
9
|
export type { firstlyData };
|
|
10
|
-
export { KitAuthUser, KitAuthAccount, AuthProvider, KitAuthUserSession }
|
|
11
|
-
export { AuthController } from './AuthController';
|
|
10
|
+
export { KitAuthUser, KitAuthAccount, AuthProvider, KitAuthUserSession };
|
|
12
11
|
export type AuthorizationURLOptions = Record<string, {
|
|
13
12
|
scopes?: string[];
|
|
14
13
|
}>;
|