firstly 0.0.12 → 0.0.14
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 +16 -0
- package/esm/ROUTES.d.ts +2 -0
- package/esm/ROUTES.js +1 -0
- package/esm/api/index.d.ts +9 -0
- package/esm/api/index.js +3 -1
- package/esm/auth/AuthController.d.ts +12 -23
- package/esm/auth/AuthController.js +12 -31
- package/esm/auth/server/AuthController.server.d.ts +11 -11
- package/esm/auth/server/AuthController.server.js +99 -34
- package/esm/auth/server/handleGuard.d.ts +16 -0
- package/esm/auth/server/handleGuard.js +67 -0
- package/esm/auth/server/helperFirstly.d.ts +1 -1
- package/esm/auth/server/helperFirstly.js +1 -0
- package/esm/auth/server/index.d.ts +3 -1
- package/esm/auth/server/index.js +3 -1
- package/esm/auth/server/module.d.ts +105 -89
- package/esm/auth/server/module.js +55 -42
- package/esm/auth/server/providers/github.d.ts +4 -2
- package/esm/auth/server/providers/github.js +2 -2
- package/esm/auth/static/assets/Page-B0XXxe0N.d.ts +6 -0
- package/esm/auth/static/assets/Page-B0XXxe0N.js +1 -0
- package/esm/auth/static/assets/Page-DdKMiUZn.d.ts +6 -0
- package/esm/auth/static/assets/Page-DdKMiUZn.js +20 -0
- package/esm/auth/static/assets/Page-UV_hqY7I.d.ts +6 -0
- package/esm/auth/static/assets/Page-UV_hqY7I.js +1 -0
- package/esm/auth/static/assets/Page-mK42zGEw.css +1 -0
- package/esm/auth/static/assets/index-C9jzxOBu.d.ts +151 -0
- package/esm/auth/static/assets/index-C9jzxOBu.js +42 -0
- package/esm/auth/static/assets/index-DKWpA6v7.css +4 -0
- package/esm/auth/static/index.html +11 -11
- package/esm/auth/types.d.ts +26 -3
- package/esm/bin/cmd.js +423 -152
- package/esm/cellsBuildor.js +1 -1
- package/esm/common.d.ts +5 -0
- package/esm/common.js +8 -0
- package/esm/cron/server/index.js +1 -1
- package/esm/feedback/FeedbackController.js +58 -53
- package/esm/feedback/server/index.d.ts +6 -15
- package/esm/feedback/server/index.js +4 -5
- package/esm/feedback/types.d.ts +14 -0
- package/esm/feedback/types.js +4 -0
- package/esm/feedback/ui/DialogIssue.svelte +131 -119
- package/esm/feedback/ui/DialogIssue.svelte.d.ts +20 -18
- package/esm/feedback/ui/DialogIssues.svelte +108 -99
- package/esm/feedback/ui/DialogIssues.svelte.d.ts +20 -18
- package/esm/feedback/ui/DialogMilestones.svelte +40 -34
- package/esm/feedback/ui/DialogMilestones.svelte.d.ts +18 -16
- package/esm/feedback/ui/Feedback.svelte +11 -9
- package/esm/feedback/ui/Feedback.svelte.d.ts +16 -14
- package/esm/index.d.ts +2 -5
- package/esm/index.js +2 -8
- package/esm/mail/server/index.d.ts +9 -2
- package/esm/mail/server/index.js +3 -1
- package/esm/mail/templates/DefaultMail.svelte +81 -61
- package/esm/mail/templates/DefaultMail.svelte.d.ts +28 -26
- package/esm/server/index.d.ts +0 -0
- package/esm/server/index.js +1 -0
- package/esm/storeItem.d.ts +1 -4
- package/esm/storeItem.js +1 -1
- package/esm/storeList.d.ts +1 -4
- package/esm/sveltekit/server/index.d.ts +3 -9
- package/esm/sveltekit/server/index.js +3 -0
- package/esm/ui/Button.svelte +112 -89
- package/esm/ui/Button.svelte.d.ts +34 -24
- package/esm/ui/Clipboardable.svelte +24 -17
- package/esm/ui/Clipboardable.svelte.d.ts +34 -23
- package/esm/ui/Field.svelte +328 -285
- package/esm/ui/Field.svelte.d.ts +15 -8
- package/esm/ui/FieldGroup.svelte +112 -91
- package/esm/ui/FieldGroup.svelte.d.ts +17 -6
- package/esm/ui/Grid.svelte +322 -308
- package/esm/ui/Grid.svelte.d.ts +17 -6
- package/esm/ui/GridLoading.svelte +28 -27
- package/esm/ui/GridLoading.svelte.d.ts +19 -17
- package/esm/ui/GridPaginate.svelte +68 -61
- package/esm/ui/GridPaginate.svelte.d.ts +21 -19
- package/esm/ui/Icon.svelte +116 -80
- package/esm/ui/Icon.svelte.d.ts +52 -43
- package/esm/ui/Loading.svelte +10 -8
- package/esm/ui/Loading.svelte.d.ts +29 -18
- package/esm/ui/Tooltip.svelte +38 -35
- package/esm/ui/Tooltip.svelte.d.ts +30 -20
- package/esm/ui/dialog/DialogForm.svelte +70 -63
- package/esm/ui/dialog/DialogForm.svelte.d.ts +18 -16
- package/esm/ui/dialog/DialogManagement.svelte +74 -74
- package/esm/ui/dialog/DialogManagement.svelte.d.ts +22 -21
- package/esm/ui/dialog/DialogPrimitive.svelte +82 -76
- package/esm/ui/dialog/DialogPrimitive.svelte.d.ts +35 -25
- package/esm/ui/dialog/FormEditAction.svelte +58 -50
- package/esm/ui/dialog/FormEditAction.svelte.d.ts +13 -6
- package/esm/ui/dialog/dialog.d.ts +1 -4
- package/esm/ui/internals/FieldContainer.svelte +24 -17
- package/esm/ui/internals/FieldContainer.svelte.d.ts +37 -28
- package/esm/ui/internals/Input.svelte +136 -102
- package/esm/ui/internals/Input.svelte.d.ts +34 -32
- package/esm/ui/internals/Textarea.svelte +60 -52
- package/esm/ui/internals/Textarea.svelte.d.ts +31 -28
- package/esm/ui/internals/select/MultiSelectMelt.svelte +243 -199
- package/esm/ui/internals/select/MultiSelectMelt.svelte.d.ts +29 -27
- package/esm/ui/internals/select/SelectMelt.svelte +254 -219
- package/esm/ui/internals/select/SelectMelt.svelte.d.ts +34 -32
- package/esm/ui/internals/select/SelectRadio.svelte +39 -33
- package/esm/ui/internals/select/SelectRadio.svelte.d.ts +24 -22
- package/esm/ui/link/Link.svelte +25 -20
- package/esm/ui/link/Link.svelte.d.ts +31 -23
- package/esm/ui/link/LinkPlus.svelte +52 -51
- package/esm/ui/link/LinkPlus.svelte.d.ts +20 -18
- package/esm/vite/index.d.ts +2 -3
- package/esm/vite/index.js +33 -26
- package/package.json +16 -20
- package/esm/auth/static/assets/Page-Bb8bFlrP.d.ts +0 -4
- package/esm/auth/static/assets/Page-Bb8bFlrP.js +0 -1
- package/esm/auth/static/assets/Page-BxomFlZ8.d.ts +0 -4
- package/esm/auth/static/assets/Page-BxomFlZ8.js +0 -1
- package/esm/auth/static/assets/Page-CaIYu0-y.d.ts +0 -6
- package/esm/auth/static/assets/Page-CaIYu0-y.js +0 -19
- package/esm/auth/static/assets/Page-MkYglNtu.css +0 -1
- package/esm/auth/static/assets/index-Bl0Bk5u0.d.ts +0 -64
- package/esm/auth/static/assets/index-Bl0Bk5u0.js +0 -2
- package/esm/auth/static/assets/index-R27C_TlP.css +0 -4
|
@@ -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 +1 @@
|
|
|
1
|
-
export declare const ff_createSession: (userId: string) => Promise<
|
|
1
|
+
export declare const ff_createSession: (userId: string) => Promise<import("..").FFAuthUserSession>;
|
|
@@ -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 };
|
package/esm/auth/server/index.js
CHANGED
|
@@ -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 };
|
|
@@ -3,11 +3,8 @@ import type { ClassType, UserInfo } from 'remult';
|
|
|
3
3
|
import { Module } from '../../api';
|
|
4
4
|
import type { RecursivePartial } from '../../utils/types';
|
|
5
5
|
import { FFAuthAccount, FFAuthUser, FFAuthUserSession } from '../Entities';
|
|
6
|
-
import type {
|
|
6
|
+
import type { FirstlyData, FirstlyDataAuth, ProviderAuthorizationURLOptions } from '../types';
|
|
7
7
|
import { initRoleFromEnv } from './helperRole';
|
|
8
|
-
export type { firstlyData };
|
|
9
|
-
export type ProviderConfigured = Record<string, ProviderAuthorizationURLOptions>;
|
|
10
|
-
export type ProviderAuthorizationURLOptions = string[];
|
|
11
8
|
export type OAuth2UserInfo = {
|
|
12
9
|
raw?: any;
|
|
13
10
|
providerUserId: string;
|
|
@@ -27,7 +24,12 @@ type AuthOptions<TUserEntity extends FFAuthUser = FFAuthUser, TSessionEntity ext
|
|
|
27
24
|
Account?: ClassType<TAccountEntity>;
|
|
28
25
|
};
|
|
29
26
|
debug?: boolean;
|
|
30
|
-
ui?: false | RecursivePartial<
|
|
27
|
+
ui?: false | RecursivePartial<FirstlyDataAuth['ui']>;
|
|
28
|
+
strings?: {
|
|
29
|
+
resetPasswordSend?: string;
|
|
30
|
+
anErrorOccurred?: string;
|
|
31
|
+
cannotSignUp?: string;
|
|
32
|
+
};
|
|
31
33
|
/** Usefull to overwrite where the static files are */
|
|
32
34
|
uiStaticPath?: string;
|
|
33
35
|
session?: {
|
|
@@ -63,52 +65,55 @@ type AuthOptions<TUserEntity extends FFAuthUser = FFAuthUser, TSessionEntity ext
|
|
|
63
65
|
roles?: string[];
|
|
64
66
|
}[];
|
|
65
67
|
password?: {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
68
|
+
mail?: {
|
|
69
|
+
reset?: {
|
|
70
|
+
send?: (args: {
|
|
71
|
+
email: string;
|
|
72
|
+
url: string;
|
|
73
|
+
}) => Promise<void>;
|
|
74
|
+
/** in secondes @default 5 minutes */
|
|
75
|
+
expiresIn?: number;
|
|
76
|
+
};
|
|
77
|
+
verify?: {
|
|
78
|
+
send?: (args: {
|
|
79
|
+
email: string;
|
|
80
|
+
url: string;
|
|
81
|
+
}) => Promise<void>;
|
|
82
|
+
/** in secondes @default 5 minutes */
|
|
83
|
+
expiresIn?: number;
|
|
84
|
+
};
|
|
85
|
+
};
|
|
86
|
+
algo?: {
|
|
87
|
+
/**
|
|
88
|
+
* Validate the password or throw an error.
|
|
89
|
+
*
|
|
90
|
+
* Here is an example (and it's the default implementation):
|
|
91
|
+
* ```
|
|
92
|
+
* function validatePassword(password: string) {
|
|
93
|
+
* if (typeof password !== 'string' || password.length < 6 || password.length > 255) {
|
|
94
|
+
* throw new EntityError({ message: 'Invalid password' })
|
|
95
|
+
* }
|
|
96
|
+
* }
|
|
97
|
+
* ```
|
|
98
|
+
*/
|
|
99
|
+
validateInput?: ({ identifier, password }: {
|
|
100
|
+
identifier: string;
|
|
101
|
+
password: string;
|
|
102
|
+
}) => void;
|
|
103
|
+
/**
|
|
104
|
+
* If you want to NOT use the default bcrypt, you can pass your own thing!
|
|
105
|
+
*/
|
|
106
|
+
hash?: (password: string) => Promise<string>;
|
|
107
|
+
/**
|
|
108
|
+
* If you want to NOT use the default bcrypt, you can pass your own thing!
|
|
109
|
+
*/
|
|
110
|
+
verify?: (password: string, hash: string) => Promise<boolean>;
|
|
85
111
|
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
112
|
/**
|
|
104
113
|
* The number of rounds to use for the bcrypt hash.
|
|
105
114
|
* @default 10
|
|
106
115
|
*/
|
|
107
116
|
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
117
|
};
|
|
113
118
|
};
|
|
114
119
|
};
|
|
@@ -135,16 +140,19 @@ export declare const getSafeOptions: <TUserEntity extends FFAuthUser = FFAuthUse
|
|
|
135
140
|
signUp: boolean;
|
|
136
141
|
password: {
|
|
137
142
|
enabled: boolean;
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
143
|
+
validateInput: ({ identifier, password }: {
|
|
144
|
+
identifier: string;
|
|
145
|
+
password: string;
|
|
146
|
+
}) => void;
|
|
147
|
+
hash: ((password: string) => Promise<string>) | ((password: string) => string);
|
|
148
|
+
verify: ((password: string, hash: string) => Promise<boolean>) | ((password: string, hash: string) => boolean);
|
|
141
149
|
};
|
|
142
150
|
otp: {
|
|
143
151
|
enabled: boolean;
|
|
144
152
|
};
|
|
145
153
|
verifiedMethod: "email" | "auto" | "manual";
|
|
146
154
|
redirectUrl: string;
|
|
147
|
-
firstlyData:
|
|
155
|
+
firstlyData: FirstlyData;
|
|
148
156
|
transformDbUserToClientUser: (session: TSessionEntity, user: TUserEntity) => UserInfo;
|
|
149
157
|
uiStaticPath: string;
|
|
150
158
|
session: {
|
|
@@ -157,52 +165,55 @@ export declare const getSafeOptions: <TUserEntity extends FFAuthUser = FFAuthUse
|
|
|
157
165
|
roles?: string[];
|
|
158
166
|
}[];
|
|
159
167
|
password?: {
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
168
|
+
mail?: {
|
|
169
|
+
reset?: {
|
|
170
|
+
send?: (args: {
|
|
171
|
+
email: string;
|
|
172
|
+
url: string;
|
|
173
|
+
}) => Promise<void>;
|
|
174
|
+
/** in secondes @default 5 minutes */
|
|
175
|
+
expiresIn?: number;
|
|
176
|
+
};
|
|
177
|
+
verify?: {
|
|
178
|
+
send?: (args: {
|
|
179
|
+
email: string;
|
|
180
|
+
url: string;
|
|
181
|
+
}) => Promise<void>;
|
|
182
|
+
/** in secondes @default 5 minutes */
|
|
183
|
+
expiresIn?: number;
|
|
184
|
+
};
|
|
185
|
+
};
|
|
186
|
+
algo?: {
|
|
187
|
+
/**
|
|
188
|
+
* Validate the password or throw an error.
|
|
189
|
+
*
|
|
190
|
+
* Here is an example (and it's the default implementation):
|
|
191
|
+
* ```
|
|
192
|
+
* function validatePassword(password: string) {
|
|
193
|
+
* if (typeof password !== 'string' || password.length < 6 || password.length > 255) {
|
|
194
|
+
* throw new EntityError({ message: 'Invalid password' })
|
|
195
|
+
* }
|
|
196
|
+
* }
|
|
197
|
+
* ```
|
|
198
|
+
*/
|
|
199
|
+
validateInput?: ({ identifier, password }: {
|
|
200
|
+
identifier: string;
|
|
201
|
+
password: string;
|
|
202
|
+
}) => void;
|
|
203
|
+
/**
|
|
204
|
+
* If you want to NOT use the default bcrypt, you can pass your own thing!
|
|
205
|
+
*/
|
|
206
|
+
hash?: (password: string) => Promise<string>;
|
|
207
|
+
/**
|
|
208
|
+
* If you want to NOT use the default bcrypt, you can pass your own thing!
|
|
209
|
+
*/
|
|
210
|
+
verify?: (password: string, hash: string) => Promise<boolean>;
|
|
179
211
|
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
212
|
/**
|
|
198
213
|
* The number of rounds to use for the bcrypt hash.
|
|
199
214
|
* @default 10
|
|
200
215
|
*/
|
|
201
216
|
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
217
|
};
|
|
207
218
|
};
|
|
208
219
|
};
|
|
@@ -220,6 +231,11 @@ export declare const getSafeOptions: <TUserEntity extends FFAuthUser = FFAuthUse
|
|
|
220
231
|
};
|
|
221
232
|
oAuths?: FFOAuth2Provider[];
|
|
222
233
|
} | undefined;
|
|
234
|
+
strings: {
|
|
235
|
+
resetPasswordSend: string;
|
|
236
|
+
anErrorOccurred: string;
|
|
237
|
+
cannotSignUp: string;
|
|
238
|
+
};
|
|
223
239
|
};
|
|
224
240
|
export declare const authModuleRaw: Module;
|
|
225
241
|
/**
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import bcrypt from '
|
|
1
|
+
import bcrypt from 'bcryptjs';
|
|
2
2
|
import { EntityError, remult } from 'remult';
|
|
3
3
|
import { red } from '@kitql/helpers';
|
|
4
4
|
import { getRelativePackagePath } from '@kitql/internals';
|
|
5
|
+
import { building } from '$app/environment';
|
|
5
6
|
import { AuthController } from '..';
|
|
6
7
|
import { FF_Role } from '../..';
|
|
7
8
|
import { Module } from '../../api';
|
|
@@ -23,42 +24,44 @@ const buildUrlOrDefault = (base, userSetting, fallback) => {
|
|
|
23
24
|
export const getSafeOptions = () => {
|
|
24
25
|
const signUp = AUTH_OPTIONS.signUp ?? true;
|
|
25
26
|
const base = AUTH_OPTIONS.ui === false ? 'NO_BASE_PATH' : (AUTH_OPTIONS.ui?.paths?.base ?? '/ff/auth');
|
|
27
|
+
const ui = AUTH_OPTIONS.ui === false
|
|
28
|
+
? undefined
|
|
29
|
+
: {
|
|
30
|
+
paths: {
|
|
31
|
+
base,
|
|
32
|
+
sign_up: signUp ? buildUrlOrDefault(base, AUTH_OPTIONS.ui?.paths?.sign_up, 'sign-up') : false,
|
|
33
|
+
sign_in: buildUrlOrDefault(base, AUTH_OPTIONS.ui?.paths?.sign_in, 'sign-in'),
|
|
34
|
+
forgot_password: buildUrlOrDefault(base, AUTH_OPTIONS.ui?.paths?.forgot_password, 'forgot-password'),
|
|
35
|
+
reset_password: buildUrlOrDefault(base, AUTH_OPTIONS.ui?.paths?.reset_password, 'reset-password'),
|
|
36
|
+
verify_email: buildUrlOrDefault(base, AUTH_OPTIONS.ui?.paths?.verify_email, 'verify-email'),
|
|
37
|
+
},
|
|
38
|
+
strings: {
|
|
39
|
+
app_name: AUTH_OPTIONS.ui?.strings?.app_name ?? '',
|
|
40
|
+
email: AUTH_OPTIONS.ui?.strings?.email ?? 'Email',
|
|
41
|
+
email_placeholder: AUTH_OPTIONS.ui?.strings?.email_placeholder ?? 'Your email address',
|
|
42
|
+
password: AUTH_OPTIONS.ui?.strings?.password ?? 'Password',
|
|
43
|
+
password_placeholder: AUTH_OPTIONS.ui?.strings?.password_placeholder ?? 'Your password',
|
|
44
|
+
confirm: AUTH_OPTIONS.ui?.strings?.confirm ?? 'Confirm',
|
|
45
|
+
reset: AUTH_OPTIONS.ui?.strings?.reset ?? 'Reset',
|
|
46
|
+
btn_sign_up: AUTH_OPTIONS.ui?.strings?.btn_sign_up ?? 'Sign up',
|
|
47
|
+
btn_sign_in: AUTH_OPTIONS.ui?.strings?.btn_sign_in ?? 'Sign in',
|
|
48
|
+
forgot_password: AUTH_OPTIONS.ui?.strings?.forgot_password ?? 'Forgot your password?',
|
|
49
|
+
send_password_reset_instructions: AUTH_OPTIONS.ui?.strings?.send_password_reset_instructions ??
|
|
50
|
+
'Send password reset instructions',
|
|
51
|
+
back_to_sign_in: AUTH_OPTIONS.ui?.strings?.back_to_sign_in ?? 'Back to sign in',
|
|
52
|
+
},
|
|
53
|
+
images: {
|
|
54
|
+
main: AUTH_OPTIONS.ui?.images?.main ?? '',
|
|
55
|
+
},
|
|
56
|
+
};
|
|
57
|
+
if (AUTH_OPTIONS.debug && !building) {
|
|
58
|
+
authModuleRaw.log.info('ui', ui);
|
|
59
|
+
}
|
|
26
60
|
const firstlyData = {
|
|
27
61
|
module: 'auth',
|
|
28
62
|
debug: AUTH_OPTIONS.debug,
|
|
29
63
|
props: {
|
|
30
|
-
ui
|
|
31
|
-
? undefined
|
|
32
|
-
: {
|
|
33
|
-
paths: {
|
|
34
|
-
base,
|
|
35
|
-
sign_up: signUp
|
|
36
|
-
? buildUrlOrDefault(base, AUTH_OPTIONS.ui?.paths?.sign_up, 'sign-up')
|
|
37
|
-
: false,
|
|
38
|
-
sign_in: buildUrlOrDefault(base, AUTH_OPTIONS.ui?.paths?.sign_in, 'sign-in'),
|
|
39
|
-
forgot_password: buildUrlOrDefault(base, AUTH_OPTIONS.ui?.paths?.forgot_password, 'forgot-password'),
|
|
40
|
-
reset_password: buildUrlOrDefault(base, AUTH_OPTIONS.ui?.paths?.reset_password, 'reset-password'),
|
|
41
|
-
verify_email: buildUrlOrDefault(base, AUTH_OPTIONS.ui?.paths?.verify_email, 'verify-email'),
|
|
42
|
-
},
|
|
43
|
-
strings: {
|
|
44
|
-
app_name: AUTH_OPTIONS.ui?.strings?.app_name ?? '',
|
|
45
|
-
email: AUTH_OPTIONS.ui?.strings?.email ?? 'Email',
|
|
46
|
-
email_placeholder: AUTH_OPTIONS.ui?.strings?.email_placeholder ?? 'Your email address',
|
|
47
|
-
password: AUTH_OPTIONS.ui?.strings?.password ?? 'Password',
|
|
48
|
-
password_placeholder: AUTH_OPTIONS.ui?.strings?.password_placeholder ?? 'Your password',
|
|
49
|
-
confirm: AUTH_OPTIONS.ui?.strings?.confirm ?? 'Confirm',
|
|
50
|
-
reset: AUTH_OPTIONS.ui?.strings?.reset ?? 'Reset',
|
|
51
|
-
btn_sign_up: AUTH_OPTIONS.ui?.strings?.btn_sign_up ?? 'Sign up',
|
|
52
|
-
btn_sign_in: AUTH_OPTIONS.ui?.strings?.btn_sign_in ?? 'Sign in',
|
|
53
|
-
forgot_password: AUTH_OPTIONS.ui?.strings?.forgot_password ?? 'Forgot your password?',
|
|
54
|
-
send_password_reset_instructions: AUTH_OPTIONS.ui?.strings?.send_password_reset_instructions ??
|
|
55
|
-
'Send password reset instructions',
|
|
56
|
-
back_to_sign_in: AUTH_OPTIONS.ui?.strings?.back_to_sign_in ?? 'Back to sign in',
|
|
57
|
-
},
|
|
58
|
-
images: {
|
|
59
|
-
main: AUTH_OPTIONS.ui?.images?.main ?? '',
|
|
60
|
-
},
|
|
61
|
-
},
|
|
64
|
+
ui,
|
|
62
65
|
},
|
|
63
66
|
};
|
|
64
67
|
let uiStaticPath = AUTH_OPTIONS.uiStaticPath ?? '';
|
|
@@ -91,29 +94,33 @@ export const getSafeOptions = () => {
|
|
|
91
94
|
};
|
|
92
95
|
};
|
|
93
96
|
}
|
|
94
|
-
function
|
|
95
|
-
if (typeof
|
|
97
|
+
function validateInput({ identifier, password }) {
|
|
98
|
+
if (typeof identifier !== 'string' || identifier.length === 0) {
|
|
99
|
+
throw new EntityError({ message: 'Invalid identifier' });
|
|
100
|
+
}
|
|
101
|
+
if (typeof password !== 'string') {
|
|
96
102
|
throw new EntityError({ message: 'Invalid password' });
|
|
97
103
|
}
|
|
104
|
+
if (password.length < 6 || password.length > 255) {
|
|
105
|
+
throw new EntityError({ message: 'Password too short or too long!' });
|
|
106
|
+
}
|
|
98
107
|
}
|
|
99
108
|
function passwordHash(password) {
|
|
100
|
-
|
|
101
|
-
return bcrypt.hashSync(password, AUTH_OPTIONS.providers?.password?.settings?.bcrypt?.saltRounds ?? 10);
|
|
109
|
+
return bcrypt.hashSync(password, AUTH_OPTIONS.providers?.password?.algo?.bcrypt?.saltRounds ?? 10);
|
|
102
110
|
}
|
|
103
111
|
function passwordVerify(password, hash) {
|
|
104
112
|
return bcrypt.compareSync(password, hash);
|
|
105
113
|
}
|
|
106
114
|
return {
|
|
107
115
|
User: (AUTH_OPTIONS.customEntities?.User ?? FFAuthUser),
|
|
108
|
-
Session: (AUTH_OPTIONS.customEntities?.Session ??
|
|
109
|
-
FFAuthUserSession),
|
|
116
|
+
Session: (AUTH_OPTIONS.customEntities?.Session ?? FFAuthUserSession),
|
|
110
117
|
Account: (AUTH_OPTIONS.customEntities?.Account ?? FFAuthAccount),
|
|
111
118
|
signUp,
|
|
112
119
|
password: {
|
|
113
120
|
enabled: AUTH_OPTIONS.providers?.password ? true : false,
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
121
|
+
validateInput: AUTH_OPTIONS.providers?.password?.algo?.validateInput ?? validateInput,
|
|
122
|
+
hash: AUTH_OPTIONS.providers?.password?.algo?.hash ?? passwordHash,
|
|
123
|
+
verify: AUTH_OPTIONS.providers?.password?.algo?.verify ?? passwordVerify,
|
|
117
124
|
},
|
|
118
125
|
otp: { enabled: AUTH_OPTIONS.providers?.otp ? true : false },
|
|
119
126
|
verifiedMethod: AUTH_OPTIONS.verifiedMethod ?? 'auto',
|
|
@@ -126,6 +133,12 @@ export const getSafeOptions = () => {
|
|
|
126
133
|
cookieName: AUTH_OPTIONS.session?.COOKIE_NAME ?? 'firstly_auth_session',
|
|
127
134
|
},
|
|
128
135
|
providers: AUTH_OPTIONS.providers,
|
|
136
|
+
strings: {
|
|
137
|
+
resetPasswordSend: AUTH_OPTIONS.strings?.resetPasswordSend ?? 'Mail sent ! You can now close this window.',
|
|
138
|
+
anErrorOccurred: AUTH_OPTIONS.strings?.anErrorOccurred ?? 'An error occurred, contact the administrator.',
|
|
139
|
+
cannotSignUp: AUTH_OPTIONS.strings?.cannotSignUp ??
|
|
140
|
+
"You can't signup by yourself! Contact the administrator.",
|
|
141
|
+
},
|
|
129
142
|
};
|
|
130
143
|
};
|
|
131
144
|
export const authModuleRaw = new Module({
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import type { OAuth2Tokens } from 'arctic';
|
|
2
|
+
import { GitHub } from 'arctic';
|
|
3
|
+
import type { ProviderAuthorizationURLOptions } from '../../types';
|
|
4
|
+
import { type FFOAuth2Provider, type OAuth2UserInfo } from '../module';
|
|
3
5
|
/**
|
|
4
6
|
* ## GitHub OAuth2 provider
|
|
5
7
|
*
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { GitHub
|
|
1
|
+
import { GitHub } from 'arctic';
|
|
2
2
|
import { remult } from 'remult';
|
|
3
3
|
import { env } from '$env/dynamic/private';
|
|
4
|
-
import { authModuleRaw
|
|
4
|
+
import { authModuleRaw } from '../module';
|
|
5
5
|
import { checkOAuthConfig } from './helperProvider';
|
|
6
6
|
//------------------------------
|
|
7
7
|
// For developers (future me ?), To do another OAuth2 provider:
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{v as r,x as l,aa as m,J as o,K as d,M as n,O as p,P as u,R as i}from"./index-C9jzxOBu.js";p();a[u]="src/lib/modules/admin/Page.svelte";function a(e,s){r(new.target),l(s,!1,a);var t=m("Hello from admin");return o(e,t),d({...n()})}i(a);export{a as default};
|