firstly 0.0.6 → 0.0.8
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 +26 -0
- package/esm/FF_Entity.js +20 -4
- package/esm/ROUTES.d.ts +11 -11
- package/esm/ROUTES.js +5 -5
- package/esm/SqlDatabase/FF_LogToConsole.d.ts +4 -1
- package/esm/SqlDatabase/FF_LogToConsole.js +15 -8
- package/esm/api/index.d.ts +2 -2
- package/esm/api/index.js +9 -9
- package/esm/auth/Adapter.js +1 -7
- package/esm/auth/AuthController.server.d.ts +1 -2
- package/esm/auth/AuthController.server.js +96 -65
- package/esm/auth/RoleHelpers.d.ts +1 -1
- package/esm/auth/RoleHelpers.js +9 -9
- package/esm/auth/client/Auth.d.ts +11 -4
- package/esm/auth/client/Auth.js +13 -5
- package/esm/auth/{Entities.d.ts → client/Entities.d.ts} +3 -3
- package/esm/auth/{Entities.js → client/Entities.js} +30 -14
- package/esm/auth/client/index.d.ts +5 -0
- package/esm/auth/client/index.js +5 -0
- package/esm/auth/helper.d.ts +6 -1
- package/esm/auth/helper.js +11 -4
- package/esm/auth/index.d.ts +9 -11
- package/esm/auth/index.js +74 -70
- package/esm/auth/providers/github.js +2 -1
- package/esm/auth/providers/index.js +1 -1
- package/esm/auth/providers/strava.js +2 -1
- package/esm/auth/static/assets/{Page-RIbXHuZG.d.ts → Page-BEFYPjis.d.ts} +1 -1
- package/esm/auth/static/assets/{Page-RIbXHuZG.js → Page-BEFYPjis.js} +1 -1
- package/esm/auth/static/assets/Page-Cfysx_UV.d.ts +6 -0
- package/esm/auth/static/assets/Page-Cfysx_UV.js +18 -0
- package/esm/auth/static/assets/{Page-DBWJjlEQ.d.ts → Page-DtgkOCJs.d.ts} +1 -1
- package/esm/auth/static/assets/{Page-DBWJjlEQ.js → Page-DtgkOCJs.js} +1 -1
- package/esm/auth/static/assets/index-QypqCYwC.d.ts +63 -0
- package/esm/auth/static/assets/index-QypqCYwC.js +2 -0
- package/esm/auth/static/index.html +1 -1
- package/esm/auth/types.d.ts +7 -5
- package/esm/bin/cmd.js +28 -14
- package/esm/cellsBuildor.d.ts +1 -0
- package/esm/cellsBuildor.js +24 -12
- package/esm/changeLog/index.d.ts +23 -7
- package/esm/changeLog/index.js +24 -18
- package/esm/feedback/FeedbackController.d.ts +12 -3
- package/esm/feedback/FeedbackController.js +62 -11
- package/esm/feedback/index.d.ts +1 -0
- package/esm/feedback/ui/DialogIssue.svelte +28 -9
- package/esm/feedback/ui/DialogIssues.svelte +7 -2
- package/esm/handle/index.d.ts +1 -1
- package/esm/index.d.ts +4 -2
- package/esm/index.js +1 -1
- package/esm/mail/index.js +1 -1
- package/esm/mail/templates/DefaultMail.svelte +1 -1
- package/esm/ui/Field.svelte +2 -10
- package/esm/ui/GridPaginate.svelte +7 -7
- package/esm/ui/GridPaginate.svelte.d.ts +1 -1
- package/esm/vite/index.js +4 -1
- package/package.json +8 -8
- package/esm/auth/static/assets/Page-apb_xgZT.d.ts +0 -6
- package/esm/auth/static/assets/Page-apb_xgZT.js +0 -18
- package/esm/auth/static/assets/index-qfq98Nyd.d.ts +0 -63
- package/esm/auth/static/assets/index-qfq98Nyd.js +0 -2
package/esm/auth/client/Auth.js
CHANGED
|
@@ -6,15 +6,26 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
6
6
|
};
|
|
7
7
|
import { 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
|
|
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:
|
|
107
|
+
BackendMethod({ allowed: true })
|
|
100
108
|
], Auth, "invite", null);
|
|
101
109
|
__decorate([
|
|
102
110
|
BackendMethod({ allowed: true })
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { BaseEnum } from '
|
|
2
|
-
import type { BaseEnumOptions } from '
|
|
1
|
+
import { BaseEnum } from '../..';
|
|
2
|
+
import type { BaseEnumOptions } from '../..';
|
|
3
3
|
export declare const FF_Auth_Role: {
|
|
4
4
|
readonly Admin: "FF_Auth_Role.Admin";
|
|
5
5
|
};
|
|
@@ -7,7 +7,7 @@ export declare class FFAuthUser {
|
|
|
7
7
|
id: string;
|
|
8
8
|
createdAt: Date;
|
|
9
9
|
updatedAt?: Date;
|
|
10
|
-
|
|
10
|
+
identifier: string;
|
|
11
11
|
roles: string[];
|
|
12
12
|
accounts: FFAuthAccount[];
|
|
13
13
|
sessions: FFAuthUserSession[];
|
|
@@ -5,8 +5,8 @@ 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 {
|
|
9
|
-
import { BaseEnum, FF_Role } from '
|
|
8
|
+
import { Fields, Relations, Validators, ValueListFieldType } from 'remult';
|
|
9
|
+
import { BaseEnum, FF_Entity, FF_Role } from '../..';
|
|
10
10
|
export const FF_Auth_Role = {
|
|
11
11
|
Admin: 'FF_Auth_Role.Admin',
|
|
12
12
|
};
|
|
@@ -14,7 +14,7 @@ let FFAuthUser = class FFAuthUser {
|
|
|
14
14
|
id;
|
|
15
15
|
createdAt;
|
|
16
16
|
updatedAt;
|
|
17
|
-
|
|
17
|
+
identifier;
|
|
18
18
|
roles = [];
|
|
19
19
|
accounts;
|
|
20
20
|
sessions;
|
|
@@ -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.
|
|
37
|
+
if (e.identifier?.length < 2)
|
|
37
38
|
throw 'Must be at least 2 characters long';
|
|
38
39
|
},
|
|
39
40
|
],
|
|
40
41
|
})
|
|
41
|
-
], FFAuthUser.prototype, "
|
|
42
|
+
], FFAuthUser.prototype, "identifier", void 0);
|
|
42
43
|
__decorate([
|
|
43
|
-
Fields.
|
|
44
|
+
Fields.json(() => [], {
|
|
45
|
+
inputType: 'selectEnum',
|
|
44
46
|
valueConverter: {
|
|
45
|
-
toDb: (x) => (x ? x.join(',') :
|
|
46
|
-
|
|
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
|
-
|
|
67
|
+
FF_Entity('ff_auth.users', {
|
|
58
68
|
allowApiCrud: [FF_Auth_Role.Admin, FF_Role.Admin],
|
|
59
|
-
caption: 'Auth - Users',
|
|
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
|
-
|
|
120
|
+
FF_Entity('ff_auth.accounts', {
|
|
111
121
|
allowApiCrud: [FF_Auth_Role.Admin, FF_Role.Admin],
|
|
112
|
-
caption: 'Auth - Accounts',
|
|
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
|
-
|
|
151
|
+
FF_Entity('ff_auth.users_sessions', {
|
|
137
152
|
allowApiCrud: [FF_Auth_Role.Admin, FF_Role.Admin],
|
|
138
|
-
caption: 'Auth - Users sessions',
|
|
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_Auth_Role } from './Entities';
|
|
2
6
|
export { Auth };
|
|
7
|
+
export { FFAuthUser, FFAuthAccount, FFAuthProvider, FFAuthUserSession };
|
package/esm/auth/client/index.js
CHANGED
|
@@ -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_Auth_Role } from './Entities';
|
|
2
6
|
export { Auth };
|
|
7
|
+
export { FFAuthUser, FFAuthAccount, FFAuthProvider, FFAuthUserSession };
|
package/esm/auth/helper.d.ts
CHANGED
|
@@ -1 +1,6 @@
|
|
|
1
|
-
|
|
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>;
|
package/esm/auth/helper.js
CHANGED
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
import { remult } from 'remult';
|
|
2
2
|
import { lucia } from '.';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
/**
|
|
4
|
+
* Create or extend a session for a user.
|
|
5
|
+
* If you pass a session, it will extend it.
|
|
6
|
+
*/
|
|
7
|
+
export async function createOrExtendSession(userId, session) {
|
|
8
|
+
const sessionToUser = session ? session : await lucia.createSession(userId, {});
|
|
9
|
+
const sessionCookie = lucia.createSessionCookie(sessionToUser.id);
|
|
10
|
+
remult.context.setCookie(sessionCookie.name, sessionCookie.value, {
|
|
11
|
+
path: '/',
|
|
12
|
+
...sessionCookie.attributes,
|
|
13
|
+
});
|
|
7
14
|
}
|
package/esm/auth/index.d.ts
CHANGED
|
@@ -1,21 +1,17 @@
|
|
|
1
1
|
import type { OAuth2Provider as ArcticOAuth2Provider, OAuth2ProviderWithPKCE as ArcticOAuth2ProviderWithPKCE } from 'arctic';
|
|
2
2
|
import { Lucia, type SessionCookieOptions } from 'lucia';
|
|
3
3
|
import type { ClassType, UserInfo } from 'remult';
|
|
4
|
-
import { Log } from '@kitql/helpers';
|
|
5
4
|
import type { Module } from '../api';
|
|
6
5
|
import type { RecursivePartial, ResolvedType } from '../utils/types';
|
|
7
|
-
import { FFAuthAccount,
|
|
6
|
+
import { FFAuthAccount, FFAuthUser, FFAuthUserSession } from './client/Entities';
|
|
8
7
|
import type { firstlyData, firstlyDataAuth } from './types';
|
|
9
8
|
export type { firstlyData };
|
|
10
|
-
export { FFAuthUser, FFAuthAccount, FFAuthProvider, FFAuthUserSession };
|
|
11
9
|
export type AuthorizationURLOptions = Record<string, {
|
|
12
10
|
scopes?: string[];
|
|
13
11
|
}>;
|
|
14
12
|
export type DynamicAuthorizationURLOptions<T extends FFOAuth2Provider[] = FFOAuth2Provider[]> = T extends Array<infer O> ? O extends FFOAuth2Provider ? {
|
|
15
13
|
[P in O['name']]: ReturnType<O['authorizationURLOptions']>;
|
|
16
14
|
} : never : never;
|
|
17
|
-
export declare const logAuth: Log;
|
|
18
|
-
export { FF_Auth_Role } from './Entities';
|
|
19
15
|
type OAuth2UserInfo = {
|
|
20
16
|
raw?: any;
|
|
21
17
|
providerUserId: string;
|
|
@@ -37,7 +33,9 @@ type AuthOptions<TUserEntity extends FFAuthUser = FFAuthUser, TSessionEntity ext
|
|
|
37
33
|
};
|
|
38
34
|
debug?: boolean;
|
|
39
35
|
ui?: false | RecursivePartial<firstlyDataAuth['ui']>;
|
|
40
|
-
/**
|
|
36
|
+
/** Usefull to overwrite where the static files are */
|
|
37
|
+
uiStaticPath?: string;
|
|
38
|
+
/** in secondes @default 30 days */
|
|
41
39
|
sessionExpiresIn?: number;
|
|
42
40
|
sessionCookie?: SessionCookieOptions;
|
|
43
41
|
defaultRedirect?: string;
|
|
@@ -61,6 +59,7 @@ type AuthOptions<TUserEntity extends FFAuthUser = FFAuthUser, TSessionEntity ext
|
|
|
61
59
|
email: string;
|
|
62
60
|
url: string;
|
|
63
61
|
}) => Promise<void>;
|
|
62
|
+
transformDbUserToClientUser?: (session: any, user: TUserEntity) => DatabaseUserAttributes;
|
|
64
63
|
providers?: {
|
|
65
64
|
demo?: {
|
|
66
65
|
name: string;
|
|
@@ -122,13 +121,15 @@ export declare const getSafeOptions: () => {
|
|
|
122
121
|
verifiedMethod: "email" | "auto" | "manual";
|
|
123
122
|
redirectUrl: string;
|
|
124
123
|
firstlyData: firstlyData;
|
|
124
|
+
transformDbUserToClientUser: (session: any, user: FFAuthUser) => DatabaseUserAttributes;
|
|
125
|
+
uiStaticPath: string;
|
|
125
126
|
};
|
|
126
127
|
/**
|
|
127
128
|
* To enable authentication in your app in a few lines of code.
|
|
128
129
|
* _Info: index: -777_
|
|
129
130
|
*/
|
|
130
131
|
export declare const auth: (o: AuthOptions) => Module;
|
|
131
|
-
export declare
|
|
132
|
+
export declare let lucia: Lucia<Record<any, any>, UserInfo>;
|
|
132
133
|
declare module 'lucia' {
|
|
133
134
|
interface Register {
|
|
134
135
|
Lucia: typeof lucia;
|
|
@@ -138,10 +139,7 @@ declare module 'lucia' {
|
|
|
138
139
|
interface DatabaseSessionAttributes {
|
|
139
140
|
}
|
|
140
141
|
}
|
|
141
|
-
interface DatabaseUserAttributes {
|
|
142
|
-
id: string;
|
|
143
|
-
name: string;
|
|
144
|
-
roles: string[];
|
|
142
|
+
interface DatabaseUserAttributes extends UserInfo {
|
|
145
143
|
session: {
|
|
146
144
|
id: string;
|
|
147
145
|
expiresAt: Date;
|
package/esm/auth/index.js
CHANGED
|
@@ -2,33 +2,29 @@ import { redirect } from '@sveltejs/kit';
|
|
|
2
2
|
import { DEV } from 'esm-env';
|
|
3
3
|
import { Lucia, TimeSpan } from 'lucia';
|
|
4
4
|
import { remult } from 'remult';
|
|
5
|
-
import {
|
|
5
|
+
import { red } from '@kitql/helpers';
|
|
6
6
|
import { getRelativePackagePath, read } from '@kitql/internals';
|
|
7
7
|
import { env } from '$env/dynamic/private';
|
|
8
8
|
import { FF_Role } from '../';
|
|
9
9
|
import { RemultLuciaAdapter } from './Adapter';
|
|
10
10
|
import { AuthControllerServer } from './AuthController.server';
|
|
11
|
-
import { Auth } from './client';
|
|
12
|
-
import { FF_Auth_Role, FFAuthAccount, FFAuthProvider, FFAuthUser, FFAuthUserSession, } from './Entities';
|
|
13
|
-
import {
|
|
11
|
+
import { Auth, logAuth } from './client';
|
|
12
|
+
import { FF_Auth_Role, FFAuthAccount, FFAuthProvider, FFAuthUser, FFAuthUserSession, } from './client/Entities';
|
|
13
|
+
import { createOrExtendSession } from './helper';
|
|
14
14
|
import { initRoleFromEnv } from './RoleHelpers';
|
|
15
|
-
export { FFAuthUser, FFAuthAccount, FFAuthProvider, FFAuthUserSession };
|
|
16
|
-
export const logAuth = new Log('firstly | auth');
|
|
17
|
-
export { FF_Auth_Role } from './Entities';
|
|
18
15
|
export let AUTH_OPTIONS = { ui: {} };
|
|
19
16
|
const buildUrlOrDefault = (base, userSetting, fallback) => {
|
|
20
|
-
if (userSetting) {
|
|
21
|
-
return
|
|
17
|
+
if (userSetting === false) {
|
|
18
|
+
return false;
|
|
22
19
|
}
|
|
23
|
-
|
|
20
|
+
if (userSetting === undefined) {
|
|
21
|
+
return `${base}/${fallback}`;
|
|
22
|
+
}
|
|
23
|
+
return `${base}/${userSetting}`;
|
|
24
24
|
};
|
|
25
25
|
export const getSafeOptions = () => {
|
|
26
26
|
const signUp = AUTH_OPTIONS.signUp ?? true;
|
|
27
27
|
const base = AUTH_OPTIONS.ui === false ? 'NO_BASE_PATH' : AUTH_OPTIONS.ui?.paths?.base ?? '/ff/auth';
|
|
28
|
-
// const oAuths =
|
|
29
|
-
// AUTH_OPTIONS.providers?.oAuths?.map((o) => {
|
|
30
|
-
// return o.name
|
|
31
|
-
// }) ?? []
|
|
32
28
|
const firstlyData = {
|
|
33
29
|
module: 'auth',
|
|
34
30
|
debug: AUTH_OPTIONS.debug,
|
|
@@ -48,6 +44,8 @@ export const getSafeOptions = () => {
|
|
|
48
44
|
email: AUTH_OPTIONS.ui?.strings?.email ?? 'Email',
|
|
49
45
|
email_placeholder: AUTH_OPTIONS.ui?.strings?.email_placeholder ?? 'Your email address',
|
|
50
46
|
password: AUTH_OPTIONS.ui?.strings?.password ?? 'Password',
|
|
47
|
+
confirm: AUTH_OPTIONS.ui?.strings?.confirm ?? 'Confirm',
|
|
48
|
+
reset: AUTH_OPTIONS.ui?.strings?.reset ?? 'Reset',
|
|
51
49
|
btn_sign_up: AUTH_OPTIONS.ui?.strings?.btn_sign_up ?? 'Sign up',
|
|
52
50
|
btn_sign_in: AUTH_OPTIONS.ui?.strings?.btn_sign_in ?? 'Sign in',
|
|
53
51
|
forgot_password: AUTH_OPTIONS.ui?.strings?.forgot_password ?? 'Forgot your password?',
|
|
@@ -58,11 +56,45 @@ export const getSafeOptions = () => {
|
|
|
58
56
|
},
|
|
59
57
|
},
|
|
60
58
|
};
|
|
59
|
+
let uiStaticPath = AUTH_OPTIONS.uiStaticPath ?? '';
|
|
60
|
+
if (!AUTH_OPTIONS.uiStaticPath) {
|
|
61
|
+
const installedFirstlyPath = getRelativePackagePath('firstly');
|
|
62
|
+
if (installedFirstlyPath) {
|
|
63
|
+
uiStaticPath = `${installedFirstlyPath}/esm/auth/static/`;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
61
66
|
let redirectUrl = AUTH_OPTIONS.defaultRedirect ?? '/';
|
|
62
67
|
if (!redirectUrl.startsWith('/')) {
|
|
63
68
|
logAuth.error(`Invalid redirect url ${red(redirectUrl)} (it should be a local one starting with /)`);
|
|
64
69
|
redirectUrl = '/';
|
|
65
70
|
}
|
|
71
|
+
let transformDbUserToClientUserToUse;
|
|
72
|
+
if (AUTH_OPTIONS.transformDbUserToClientUser) {
|
|
73
|
+
transformDbUserToClientUserToUse = AUTH_OPTIONS.transformDbUserToClientUser;
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
// Need in src/app.d.ts this code to be able to have the correct transformDbUserToClientUser returned type.
|
|
77
|
+
// In the lib, let's force to this default
|
|
78
|
+
/**
|
|
79
|
+
* declare module 'remult' {
|
|
80
|
+
* export interface UserInfo {
|
|
81
|
+
* specificThing: string
|
|
82
|
+
* }
|
|
83
|
+
* }
|
|
84
|
+
*/
|
|
85
|
+
// @ts-ignore
|
|
86
|
+
transformDbUserToClientUserToUse = (session, user) => {
|
|
87
|
+
return {
|
|
88
|
+
id: user.id,
|
|
89
|
+
name: user.identifier,
|
|
90
|
+
roles: user.roles,
|
|
91
|
+
session: {
|
|
92
|
+
id: session.id,
|
|
93
|
+
expiresAt: session.expiresAt,
|
|
94
|
+
},
|
|
95
|
+
};
|
|
96
|
+
};
|
|
97
|
+
}
|
|
66
98
|
return {
|
|
67
99
|
User: AUTH_OPTIONS.customEntities?.User ?? FFAuthUser,
|
|
68
100
|
Session: AUTH_OPTIONS.customEntities?.Session ?? FFAuthUserSession,
|
|
@@ -73,6 +105,8 @@ export const getSafeOptions = () => {
|
|
|
73
105
|
verifiedMethod: AUTH_OPTIONS.verifiedMethod ?? 'auto',
|
|
74
106
|
redirectUrl,
|
|
75
107
|
firstlyData,
|
|
108
|
+
transformDbUserToClientUser: transformDbUserToClientUserToUse,
|
|
109
|
+
uiStaticPath,
|
|
76
110
|
};
|
|
77
111
|
};
|
|
78
112
|
/**
|
|
@@ -93,6 +127,23 @@ export const auth = (o) => {
|
|
|
93
127
|
Auth.signInOTPFn = AuthControllerServer.signInOTP;
|
|
94
128
|
Auth.verifyOtpFn = AuthControllerServer.verifyOtp;
|
|
95
129
|
Auth.signInOAuthGetUrlFn = AuthControllerServer.signInOAuthGetUrl;
|
|
130
|
+
const adapter = new RemultLuciaAdapter();
|
|
131
|
+
const defaultExpiresIn = 60 * 60 * 24 * 30; // 30 days
|
|
132
|
+
const sessionExpiresIn = new TimeSpan(AUTH_OPTIONS.sessionExpiresIn ?? defaultExpiresIn, 's');
|
|
133
|
+
lucia = new Lucia(adapter, {
|
|
134
|
+
sessionExpiresIn,
|
|
135
|
+
sessionCookie: {
|
|
136
|
+
name: AUTH_OPTIONS.sessionCookie?.name ?? 'firstly_auth_session',
|
|
137
|
+
expires: AUTH_OPTIONS.sessionCookie?.expires,
|
|
138
|
+
attributes: {
|
|
139
|
+
// set to `true` when using HTTPS
|
|
140
|
+
secure: !DEV,
|
|
141
|
+
...AUTH_OPTIONS.sessionCookie?.attributes,
|
|
142
|
+
},
|
|
143
|
+
},
|
|
144
|
+
getSessionAttributes: (attributes) => attributes,
|
|
145
|
+
getUserAttributes: (attributes) => attributes,
|
|
146
|
+
});
|
|
96
147
|
return {
|
|
97
148
|
name: 'auth',
|
|
98
149
|
index: -777,
|
|
@@ -104,19 +155,12 @@ export const auth = (o) => {
|
|
|
104
155
|
if (sessionId) {
|
|
105
156
|
const { session, user } = await lucia.validateSession(sessionId);
|
|
106
157
|
if (session && session.fresh) {
|
|
107
|
-
|
|
108
|
-
event.cookies.set(sessionCookie.name, sessionCookie.value, {
|
|
109
|
-
path: '/',
|
|
110
|
-
...sessionCookie.attributes,
|
|
111
|
-
});
|
|
158
|
+
await createOrExtendSession(session.id, session);
|
|
112
159
|
}
|
|
113
160
|
remult.user = user ?? undefined;
|
|
114
161
|
}
|
|
115
162
|
},
|
|
116
163
|
earlyReturn: async ({ event, resolve }) => {
|
|
117
|
-
// if (AUTH_OPTIONS.ui === false) {
|
|
118
|
-
// return { early: false }
|
|
119
|
-
// }
|
|
120
164
|
const oSafe = getSafeOptions();
|
|
121
165
|
if (event.url.pathname === oSafe.firstlyData.props.ui?.paths?.verify_email) {
|
|
122
166
|
const token = event.url.searchParams.get('token') ?? '';
|
|
@@ -138,19 +182,12 @@ export const auth = (o) => {
|
|
|
138
182
|
account.expiresAt = undefined;
|
|
139
183
|
account.lastVerifiedAt = new Date();
|
|
140
184
|
await remult.repo(oSafe.Account).save(account);
|
|
141
|
-
await
|
|
185
|
+
await createOrExtendSession(account.userId);
|
|
142
186
|
redirect(302, oSafe.redirectUrl);
|
|
143
187
|
}
|
|
144
|
-
// For lib author (us), it's good to have this local path.
|
|
145
|
-
let staticPath = './src/lib/auth/static/';
|
|
146
|
-
// For users, let's serve the static files from the installed package
|
|
147
|
-
const installedFirstlyPath = getRelativePackagePath('firstly');
|
|
148
|
-
if (installedFirstlyPath) {
|
|
149
|
-
staticPath = `${installedFirstlyPath}/esm/auth/static/`;
|
|
150
|
-
}
|
|
151
188
|
if (oSafe.firstlyData.props.ui?.paths?.base &&
|
|
152
189
|
event.url.pathname.startsWith(oSafe.firstlyData.props.ui.paths.base)) {
|
|
153
|
-
const content = read(`${
|
|
190
|
+
const content = read(`${oSafe.uiStaticPath}index.html`);
|
|
154
191
|
return {
|
|
155
192
|
early: true,
|
|
156
193
|
resolve: new Response(content + `<script>const firstlyData = ${JSON.stringify(oSafe.firstlyData)}</script>`, {
|
|
@@ -159,7 +196,7 @@ export const auth = (o) => {
|
|
|
159
196
|
};
|
|
160
197
|
}
|
|
161
198
|
if (event.url.pathname.startsWith('/api/static')) {
|
|
162
|
-
const content = read(`${
|
|
199
|
+
const content = read(`${oSafe.uiStaticPath}${event.url.pathname.replaceAll('/api/static/', '')}`);
|
|
163
200
|
if (content) {
|
|
164
201
|
const seg = event.url.pathname.split('.');
|
|
165
202
|
const map = {
|
|
@@ -223,7 +260,7 @@ export const auth = (o) => {
|
|
|
223
260
|
for (let i = 0; i < info.nameOptions.length; i++) {
|
|
224
261
|
const existingUser = await remult
|
|
225
262
|
.repo(oSafe.User)
|
|
226
|
-
.findOne({ where: {
|
|
263
|
+
.findOne({ where: { identifier: info.nameOptions[i] } });
|
|
227
264
|
if (existingUser) {
|
|
228
265
|
// Don't do anything
|
|
229
266
|
}
|
|
@@ -236,7 +273,7 @@ export const auth = (o) => {
|
|
|
236
273
|
nameToUse = `${info.nameOptions[0]}-${info.providerUserId}`;
|
|
237
274
|
}
|
|
238
275
|
const user = remult.repo(oSafe.User).create();
|
|
239
|
-
user.
|
|
276
|
+
user.identifier = nameToUse;
|
|
240
277
|
account = remult.repo(oSafe.Account).create();
|
|
241
278
|
account.provider = keyState;
|
|
242
279
|
account.providerUserId = info.providerUserId;
|
|
@@ -250,7 +287,7 @@ export const auth = (o) => {
|
|
|
250
287
|
account.token = tokens.accessToken;
|
|
251
288
|
await remult.repo(oSafe.Account).save(account);
|
|
252
289
|
}
|
|
253
|
-
await
|
|
290
|
+
await createOrExtendSession(account.userId);
|
|
254
291
|
event.cookies.delete(`${keyState}_oauth_state`, { path: '/' });
|
|
255
292
|
event.cookies.delete(`code_verifier`, { path: '/' });
|
|
256
293
|
}
|
|
@@ -264,38 +301,5 @@ export const auth = (o) => {
|
|
|
264
301
|
},
|
|
265
302
|
};
|
|
266
303
|
};
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
export const lucia = new Lucia(adapter, {
|
|
270
|
-
sessionExpiresIn: new TimeSpan(AUTH_OPTIONS.sessionExpiresIn ?? defaultExpiresIn, 's'),
|
|
271
|
-
sessionCookie: {
|
|
272
|
-
name: AUTH_OPTIONS.sessionCookie?.name ?? 'remult_auth_session',
|
|
273
|
-
expires: AUTH_OPTIONS.sessionCookie?.expires,
|
|
274
|
-
attributes: {
|
|
275
|
-
// set to `true` when using HTTPS
|
|
276
|
-
secure: !DEV,
|
|
277
|
-
...AUTH_OPTIONS.sessionCookie?.attributes,
|
|
278
|
-
},
|
|
279
|
-
},
|
|
280
|
-
getSessionAttributes: (attributes) => {
|
|
281
|
-
return {
|
|
282
|
-
...attributes,
|
|
283
|
-
};
|
|
284
|
-
},
|
|
285
|
-
getUserAttributes(attributes) {
|
|
286
|
-
// @ts-expect-error
|
|
287
|
-
delete attributes['createdAt'];
|
|
288
|
-
// @ts-expect-error
|
|
289
|
-
delete attributes['updatedAt'];
|
|
290
|
-
// to remove relations
|
|
291
|
-
for (const key in attributes) {
|
|
292
|
-
if (attributes[key] === undefined) {
|
|
293
|
-
delete attributes[key];
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
return attributes;
|
|
297
|
-
// return {
|
|
298
|
-
// ...attributes,
|
|
299
|
-
// }
|
|
300
|
-
},
|
|
301
|
-
});
|
|
304
|
+
// Maybe moving this to /auth/server.ts would be better, people will be able to import from firstly all the time
|
|
305
|
+
export let lucia;
|
|
@@ -2,7 +2,8 @@ import { GitHub } from 'arctic';
|
|
|
2
2
|
import { remult } from 'remult';
|
|
3
3
|
import { env } from '$env/dynamic/private';
|
|
4
4
|
import { checkOAuthConfig } from '.';
|
|
5
|
-
import {
|
|
5
|
+
import {} from '../';
|
|
6
|
+
import { logAuth } from '../client';
|
|
6
7
|
//------------------------------
|
|
7
8
|
// For developers (future me ?), To do another OAuth2 provider:
|
|
8
9
|
// Replace GITHUB / Github / github
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { cyan, gray, green, italic, yellow } from '@kitql/helpers';
|
|
2
|
-
import { logAuth } from '..';
|
|
3
2
|
import { mask } from '../../formats/strings';
|
|
3
|
+
import { logAuth } from '../client';
|
|
4
4
|
export const checkOAuthConfig = (name, clientId, secret, urlForKeys, withThrow) => {
|
|
5
5
|
if (!clientId || !secret) {
|
|
6
6
|
const msg = `Wrong configuration for ${green(name)} provider.
|
|
@@ -2,7 +2,8 @@ import { Strava } from 'arctic';
|
|
|
2
2
|
import { remult } from 'remult';
|
|
3
3
|
import { env } from '$env/dynamic/private';
|
|
4
4
|
import { checkOAuthConfig } from '.';
|
|
5
|
-
import {
|
|
5
|
+
import {} from '../';
|
|
6
|
+
import { logAuth } from '../client';
|
|
6
7
|
/**
|
|
7
8
|
* ## Strava OAuth2 provider
|
|
8
9
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{S as l,b as d,a as f,d as i,h as m,M as p,t as u,n as r,z as h}from"./index-
|
|
1
|
+
import{S as l,b as d,a as f,d as i,h as m,M as p,t as u,n as r,z as h}from"./index-QypqCYwC.js";function c(s){let e;const n={c:function(){e=p("Hello from admin")},l:function(t){throw new Error("options.hydrate only works if the component was compiled with the `hydratable: true` option")},m:function(t,o){u(t,e,o)},p:r,i:r,o:r,d:function(t){t&&h(e)}};return i("SvelteRegisterBlock",{block:n,id:c.name,type:"component",source:"",ctx:s}),n}function w(s,e){let{$$slots:n={},$$scope:a}=e;m("Page",n,[]);const t=[];return Object.keys(e).forEach(o=>{!~t.indexOf(o)&&o.slice(0,2)!=="$$"&&o!=="slot"&&console.warn(`<Page> was created with unknown prop '${o}'`)}),[]}class v extends l{constructor(e){super(e),d(this,e,w,c,f,{}),i("SvelteRegisterComponent",{component:this,tagName:"Page",options:e,id:c.name})}}export{v as default};
|