firstly 0.2.1 → 0.4.0
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 +65 -0
- package/esm/SqlDatabase/FF_LogToConsole.js +9 -14
- package/esm/carbone/CarboneController.js +2 -1
- package/esm/changeLog/index.d.ts +0 -10
- package/esm/{internals → core}/BaseEnum.d.ts +1 -1
- package/esm/core/FF_Entity.js +5 -0
- package/esm/core/helper.d.ts +2 -0
- package/esm/core/helper.js +3 -0
- package/esm/core/index.d.ts +0 -0
- package/esm/core/index.js +5 -0
- package/esm/core/tailwind.d.ts +21 -0
- package/esm/core/tailwind.js +22 -0
- package/esm/core/tryCatch.d.ts +44 -0
- package/esm/core/tryCatch.js +34 -0
- package/esm/cron/server/index.js +1 -1
- package/esm/feedback/FeedbackController.js +3 -2
- package/esm/feedback/index.d.ts +7 -2
- package/esm/feedback/index.js +1 -2
- package/esm/feedback/server/index.d.ts +0 -5
- package/esm/feedback/server/index.js +1 -1
- package/esm/formats/strings.js +2 -2
- package/esm/index.d.ts +16 -0
- package/esm/index.js +13 -0
- package/esm/svelte/FF_Repo.svelte.d.ts +9 -2
- package/esm/svelte/FF_Repo.svelte.js +40 -17
- package/esm/svelte/class/SP.svelte.js +14 -2
- package/esm/svelte/helpers/debounce.js +1 -1
- package/esm/svelte/index.d.ts +2 -24
- package/esm/svelte/index.js +2 -22
- package/esm/{ui → svelte/ui}/Icon.svelte +1 -1
- package/esm/virtual/StateDemoEnum.d.ts +3 -3
- package/esm/virtual/StateDemoEnum.js +3 -3
- package/esm/virtual/UIEntity.js +1 -2
- package/package.json +8 -39
- package/esm/auth/AuthController.d.ts +0 -58
- package/esm/auth/AuthController.js +0 -114
- package/esm/auth/Entities.d.ts +0 -47
- package/esm/auth/Entities.js +0 -182
- package/esm/auth/README.md +0 -3
- package/esm/auth/index.d.ts +0 -5
- package/esm/auth/index.js +0 -5
- package/esm/auth/server/AuthController.server.d.ts +0 -58
- package/esm/auth/server/AuthController.server.js +0 -518
- package/esm/auth/server/handleAuth.d.ts +0 -4
- package/esm/auth/server/handleAuth.js +0 -142
- package/esm/auth/server/handleGuard.d.ts +0 -22
- package/esm/auth/server/handleGuard.js +0 -34
- package/esm/auth/server/helperDb.d.ts +0 -10
- package/esm/auth/server/helperDb.js +0 -56
- package/esm/auth/server/helperFirstly.d.ts +0 -1
- package/esm/auth/server/helperFirstly.js +0 -9
- package/esm/auth/server/helperOslo.d.ts +0 -7
- package/esm/auth/server/helperOslo.js +0 -24
- package/esm/auth/server/helperRemultServer.d.ts +0 -5
- package/esm/auth/server/helperRemultServer.js +0 -44
- package/esm/auth/server/helperRole.d.ts +0 -19
- package/esm/auth/server/helperRole.js +0 -57
- package/esm/auth/server/index.d.ts +0 -8
- package/esm/auth/server/index.js +0 -8
- package/esm/auth/server/module.d.ts +0 -300
- package/esm/auth/server/module.js +0 -230
- package/esm/auth/server/providers/github.d.ts +0 -33
- package/esm/auth/server/providers/github.js +0 -87
- package/esm/auth/server/providers/helperProvider.d.ts +0 -1
- package/esm/auth/server/providers/helperProvider.js +0 -25
- package/esm/auth/static/assets/Page-BHW08QWz.css +0 -1
- package/esm/auth/static/assets/Page-BRNWcY5Z.d.ts +0 -2
- package/esm/auth/static/assets/Page-BRNWcY5Z.js +0 -1
- package/esm/auth/static/assets/Page-CFcEsGK8.d.ts +0 -2
- package/esm/auth/static/assets/Page-CFcEsGK8.js +0 -7
- package/esm/auth/static/assets/Page-tLVs5slF.d.ts +0 -2
- package/esm/auth/static/assets/Page-tLVs5slF.js +0 -1
- package/esm/auth/static/assets/index-D38rqu4x.d.ts +0 -201
- package/esm/auth/static/assets/index-D38rqu4x.js +0 -2
- package/esm/auth/static/assets/index-DKWpA6v7.css +0 -4
- package/esm/auth/static/favicon.svg +0 -79
- package/esm/auth/static/index.html +0 -13
- package/esm/auth/types.d.ts +0 -73
- package/esm/bin/cmd.d.ts +0 -1
- package/esm/bin/cmd.js +0 -793
- package/esm/feedback/ui/DialogIssue.svelte +0 -149
- package/esm/feedback/ui/DialogIssue.svelte.d.ts +0 -22
- package/esm/feedback/ui/DialogIssues.svelte +0 -114
- package/esm/feedback/ui/DialogIssues.svelte.d.ts +0 -22
- package/esm/feedback/ui/DialogMilestones.svelte +0 -43
- package/esm/feedback/ui/DialogMilestones.svelte.d.ts +0 -20
- package/esm/feedback/ui/Feedback.svelte +0 -16
- package/esm/feedback/ui/Feedback.svelte.d.ts +0 -18
- package/esm/internals/FF_Entity.d.ts +0 -2
- package/esm/internals/FF_Entity.js +0 -21
- package/esm/internals/FF_Fields.d.ts +0 -11
- package/esm/internals/FF_Fields.js +0 -144
- package/esm/internals/cellsBuildor.d.ts +0 -47
- package/esm/internals/cellsBuildor.js +0 -140
- package/esm/internals/helper.d.ts +0 -49
- package/esm/internals/helper.js +0 -162
- package/esm/internals/index.d.ts +0 -82
- package/esm/internals/index.js +0 -45
- package/esm/internals/storeItem.d.ts +0 -28
- package/esm/internals/storeItem.js +0 -176
- package/esm/internals/storeList.d.ts +0 -34
- package/esm/internals/storeList.js +0 -108
- package/esm/internals/theme.d.ts +0 -4
- package/esm/internals/theme.js +0 -4
- package/esm/server/index.d.ts +0 -52
- package/esm/server/index.js +0 -87
- package/esm/svelte/FF_Cell.svelte +0 -103
- package/esm/svelte/FF_Cell.svelte.d.ts +0 -33
- package/esm/svelte/FF_Cell_Caption.svelte +0 -20
- package/esm/svelte/FF_Cell_Caption.svelte.d.ts +0 -31
- package/esm/svelte/FF_Cell_Display.svelte +0 -61
- package/esm/svelte/FF_Cell_Display.svelte.d.ts +0 -29
- package/esm/svelte/FF_Cell_Edit.svelte +0 -104
- package/esm/svelte/FF_Cell_Edit.svelte.d.ts +0 -32
- package/esm/svelte/FF_Cell_Error.svelte +0 -20
- package/esm/svelte/FF_Cell_Error.svelte.d.ts +0 -31
- package/esm/svelte/FF_Cell_Hint.svelte +0 -20
- package/esm/svelte/FF_Cell_Hint.svelte.d.ts +0 -31
- package/esm/svelte/FF_Config.svelte +0 -29
- package/esm/svelte/FF_Config.svelte.d.ts +0 -9
- package/esm/svelte/FF_Form.svelte +0 -155
- package/esm/svelte/FF_Form.svelte.d.ts +0 -37
- package/esm/svelte/FF_Grid.svelte +0 -257
- package/esm/svelte/FF_Grid.svelte.d.ts +0 -37
- package/esm/svelte/FF_Layout.svelte +0 -62
- package/esm/svelte/FF_Layout.svelte.d.ts +0 -31
- package/esm/svelte/actions/intersection.d.ts +0 -6
- package/esm/svelte/actions/intersection.js +0 -17
- package/esm/svelte/customField.d.ts +0 -69
- package/esm/svelte/customField.js +0 -4
- package/esm/svelte/dialog/DialogManagement.svelte +0 -98
- package/esm/svelte/dialog/DialogManagement.svelte.d.ts +0 -18
- package/esm/svelte/dialog/DialogPrimitive.svelte +0 -156
- package/esm/svelte/dialog/DialogPrimitive.svelte.d.ts +0 -38
- package/esm/svelte/dialog/dialog.d.ts +0 -58
- package/esm/svelte/dialog/dialog.js +0 -130
- package/esm/svelte/ff_Config.svelte.d.ts +0 -91
- package/esm/svelte/ff_Config.svelte.js +0 -111
- package/esm/svelte/firstly.css +0 -14
- package/esm/svelte/helpers.d.ts +0 -30
- package/esm/svelte/helpers.js +0 -38
- package/esm/svelte/tryCatch.d.ts +0 -12
- package/esm/svelte/tryCatch.js +0 -18
- package/esm/sveltekit/server/index.d.ts +0 -5
- package/esm/sveltekit/server/index.js +0 -24
- package/esm/ui/Button.svelte +0 -138
- package/esm/ui/Button.svelte.d.ts +0 -13
- package/esm/ui/Clipboardable.svelte +0 -25
- package/esm/ui/Clipboardable.svelte.d.ts +0 -12
- package/esm/ui/Field.svelte +0 -382
- package/esm/ui/Field.svelte.d.ts +0 -40
- package/esm/ui/FieldGroup.svelte +0 -117
- package/esm/ui/FieldGroup.svelte.d.ts +0 -44
- package/esm/ui/Grid.svelte +0 -265
- package/esm/ui/Grid.svelte.d.ts +0 -57
- package/esm/ui/Grid2.svelte +0 -293
- package/esm/ui/Grid2.svelte.d.ts +0 -57
- package/esm/ui/GridLoading.svelte +0 -58
- package/esm/ui/GridLoading.svelte.d.ts +0 -23
- package/esm/ui/GridPaginate.svelte +0 -69
- package/esm/ui/GridPaginate.svelte.d.ts +0 -23
- package/esm/ui/GridPaginate2.svelte +0 -25
- package/esm/ui/GridPaginate2.svelte.d.ts +0 -7
- package/esm/ui/Loading.svelte +0 -16
- package/esm/ui/Loading.svelte.d.ts +0 -31
- package/esm/ui/Tooltip.svelte +0 -45
- package/esm/ui/Tooltip.svelte.d.ts +0 -32
- package/esm/ui/dialog/DialogForm.svelte +0 -76
- package/esm/ui/dialog/DialogForm.svelte.d.ts +0 -21
- package/esm/ui/dialog/DialogManagement.svelte +0 -96
- package/esm/ui/dialog/DialogManagement.svelte.d.ts +0 -26
- package/esm/ui/dialog/DialogPrimitive.svelte +0 -90
- package/esm/ui/dialog/DialogPrimitive.svelte.d.ts +0 -38
- package/esm/ui/dialog/FormEditAction.svelte +0 -62
- package/esm/ui/dialog/FormEditAction.svelte.d.ts +0 -31
- package/esm/ui/dialog/dialog.d.ts +0 -60
- package/esm/ui/dialog/dialog.js +0 -100
- package/esm/ui/index.d.ts +0 -6
- package/esm/ui/index.js +0 -20
- package/esm/ui/internals/FieldContainer.svelte +0 -39
- package/esm/ui/internals/FieldContainer.svelte.d.ts +0 -18
- package/esm/ui/internals/Input.svelte +0 -143
- package/esm/ui/internals/Input.svelte.d.ts +0 -37
- package/esm/ui/internals/Textarea.svelte +0 -66
- package/esm/ui/internals/Textarea.svelte.d.ts +0 -33
- package/esm/ui/internals/select/MultiSelectMelt.svelte +0 -260
- package/esm/ui/internals/select/MultiSelectMelt.svelte.d.ts +0 -32
- package/esm/ui/internals/select/Select2.svelte +0 -88
- package/esm/ui/internals/select/Select2.svelte.d.ts +0 -12
- package/esm/ui/internals/select/SelectMelt.svelte +0 -280
- package/esm/ui/internals/select/SelectMelt.svelte.d.ts +0 -40
- package/esm/ui/internals/select/SelectRadio.svelte +0 -43
- package/esm/ui/internals/select/SelectRadio.svelte.d.ts +0 -27
- package/esm/ui/link/Link.svelte +0 -33
- package/esm/ui/link/Link.svelte.d.ts +0 -33
- package/esm/ui/link/LinkPlus.svelte +0 -63
- package/esm/ui/link/LinkPlus.svelte.d.ts +0 -9
- package/esm/utils/tailwind.d.ts +0 -2
- package/esm/utils/tailwind.js +0 -3
- package/esm/utils/transition.d.ts +0 -9
- package/esm/utils/transition.js +0 -33
- package/esm/utils/types.js +0 -1
- /package/esm/{internals → core}/BaseEnum.js +0 -0
- /package/esm/{internals → core}/common.d.ts +0 -0
- /package/esm/{internals → core}/common.js +0 -0
- /package/esm/{utils → core}/types.d.ts +0 -0
- /package/esm/{auth → core}/types.js +0 -0
- /package/esm/{ui → svelte/ui}/Icon.svelte.d.ts +0 -0
- /package/esm/{ui → svelte/ui}/LibIcon.d.ts +0 -0
- /package/esm/{ui → svelte/ui}/LibIcon.js +0 -0
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import {} from '@sveltejs/kit';
|
|
2
|
-
import { remult } from 'remult';
|
|
3
|
-
function pathMatchesPattern(path, pattern) {
|
|
4
|
-
// Convert the pattern to a regex
|
|
5
|
-
const regexPattern = pattern.replace(/\//g, '\\/').replace(/\*/g, '.*');
|
|
6
|
-
const regex = new RegExp(`^${regexPattern}$`);
|
|
7
|
-
return regex.test(path);
|
|
8
|
-
}
|
|
9
|
-
function pathMatchesAnyPattern(path, patterns) {
|
|
10
|
-
return patterns.some((pattern) => pathMatchesPattern(path, pattern.path));
|
|
11
|
-
}
|
|
12
|
-
/**
|
|
13
|
-
* Creates a handle function with the provided route guard configuration
|
|
14
|
-
*/
|
|
15
|
-
export function handleGuard(config) {
|
|
16
|
-
return async ({ event, resolve }) => {
|
|
17
|
-
const pathname = event.url.pathname;
|
|
18
|
-
const isAuthenticated = !!remult.user;
|
|
19
|
-
const isAuthenticatedRoute = pathMatchesAnyPattern(pathname, config.guard);
|
|
20
|
-
// If user is not authenticated and tries to access an authenticated route
|
|
21
|
-
if (!isAuthenticated && isAuthenticatedRoute) {
|
|
22
|
-
// Redirect to login with the current URL as the redirect target
|
|
23
|
-
// Only redirect if we're not already on the login page
|
|
24
|
-
const isLoginPage = pathname === config.login || pathname === config.login.replace(/\/$/, '');
|
|
25
|
-
if (!isLoginPage) {
|
|
26
|
-
const encodedReturnUrl = encodeURIComponent(pathname + event.url.search);
|
|
27
|
-
const separator = config.login.includes('?') ? '&' : '?';
|
|
28
|
-
const loginUrl = `${config.login}${separator}redirect=${encodedReturnUrl}`;
|
|
29
|
-
config.redirect(302, loginUrl);
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
return resolve(event);
|
|
33
|
-
};
|
|
34
|
-
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { type UserInfo } from 'remult';
|
|
2
|
-
export declare function createSession(token: string, userId: string): Promise<import("..").FFAuthUserSession>;
|
|
3
|
-
export declare function validateSessionToken(token: string): Promise<{
|
|
4
|
-
user: UserInfo | undefined;
|
|
5
|
-
freshSession: {
|
|
6
|
-
sessionToken: string;
|
|
7
|
-
expiresAt: Date;
|
|
8
|
-
} | undefined;
|
|
9
|
-
}>;
|
|
10
|
-
export declare function invalidateSession(sessionId: string): Promise<void>;
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import { repo } from 'remult';
|
|
2
|
-
import { encodeToken } from './helperOslo';
|
|
3
|
-
import { getSafeOptions } from './module';
|
|
4
|
-
export async function createSession(token, userId) {
|
|
5
|
-
const sessionId = encodeToken(token);
|
|
6
|
-
const oSafe = getSafeOptions();
|
|
7
|
-
const session = await repo(oSafe.Session).insert({
|
|
8
|
-
id: sessionId,
|
|
9
|
-
userId,
|
|
10
|
-
expiresAt: new Date(Date.now() + oSafe.session.expiresInMs),
|
|
11
|
-
});
|
|
12
|
-
return session;
|
|
13
|
-
}
|
|
14
|
-
export async function validateSessionToken(token) {
|
|
15
|
-
const sessionId = encodeToken(token);
|
|
16
|
-
const oSafe = getSafeOptions();
|
|
17
|
-
const sessionDb = await repo(oSafe.Session).findId(sessionId);
|
|
18
|
-
if (!sessionDb) {
|
|
19
|
-
return { user: undefined, freshSession: undefined };
|
|
20
|
-
}
|
|
21
|
-
// TODO TRANSFORM
|
|
22
|
-
const session = {
|
|
23
|
-
//
|
|
24
|
-
id: sessionDb.id,
|
|
25
|
-
userId: sessionDb.userId,
|
|
26
|
-
expiresAt: sessionDb.expiresAt,
|
|
27
|
-
};
|
|
28
|
-
// TODO: Why I can't do 1 query ?!
|
|
29
|
-
const userDb = await repo(oSafe.User).findId(sessionDb.userId);
|
|
30
|
-
if (!userDb) {
|
|
31
|
-
await invalidateSession(sessionId);
|
|
32
|
-
return { user: undefined, freshSession: undefined };
|
|
33
|
-
}
|
|
34
|
-
const user = oSafe.transformDbUserToClientUser(sessionDb, userDb);
|
|
35
|
-
const sessionExpired = Date.now() >= session.expiresAt.getTime();
|
|
36
|
-
if (sessionExpired) {
|
|
37
|
-
await repo(oSafe.Session).delete(sessionId);
|
|
38
|
-
return { user: undefined, freshSession: undefined };
|
|
39
|
-
}
|
|
40
|
-
// To not renew non stop... Let's wait 10% of the session expires
|
|
41
|
-
const renewSession = Date.now() >= session.expiresAt.getTime() - oSafe.session.expiresInMs * 0.9;
|
|
42
|
-
if (renewSession) {
|
|
43
|
-
session.expiresAt = new Date(Date.now() + oSafe.session.expiresInMs);
|
|
44
|
-
await repo(oSafe.Session).update(sessionId, { expiresAt: session.expiresAt });
|
|
45
|
-
return { user, freshSession: { sessionToken: token, expiresAt: session.expiresAt } };
|
|
46
|
-
}
|
|
47
|
-
return { user, freshSession: undefined };
|
|
48
|
-
}
|
|
49
|
-
export async function invalidateSession(sessionId) {
|
|
50
|
-
const oSafe = getSafeOptions();
|
|
51
|
-
try {
|
|
52
|
-
// silent error. If the session is already deleted, it will throw an error
|
|
53
|
-
await repo(oSafe.Session).delete(sessionId);
|
|
54
|
-
}
|
|
55
|
-
catch (error) { }
|
|
56
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const ff_createSession: (userId: string) => Promise<import("..").FFAuthUserSession>;
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { createSession } from './helperDb';
|
|
2
|
-
import { generateToken } from './helperOslo';
|
|
3
|
-
import { setSessionTokenCookie } from './helperRemultServer';
|
|
4
|
-
export const ff_createSession = async (userId) => {
|
|
5
|
-
const token = generateToken();
|
|
6
|
-
const session = await createSession(token, userId);
|
|
7
|
-
setSessionTokenCookie(token, session.expiresAt);
|
|
8
|
-
return session;
|
|
9
|
-
};
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
export declare function generateId(): string;
|
|
2
|
-
export declare function generateToken(): string;
|
|
3
|
-
export declare function encodeToken(token: string): string;
|
|
4
|
-
export declare function generateAndEncodeToken(): string;
|
|
5
|
-
export declare function createDate(timeSpan_seconds: number, options?: {
|
|
6
|
-
from?: Date;
|
|
7
|
-
}): Date;
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { sha256 } from '@oslojs/crypto/sha2';
|
|
2
|
-
import { encodeBase32LowerCase, encodeBase64url, encodeHexLowerCase } from '@oslojs/encoding';
|
|
3
|
-
export function generateId() {
|
|
4
|
-
// ID with 120 bits of entropy, or about the same as UUID v4.
|
|
5
|
-
const bytes = crypto.getRandomValues(new Uint8Array(15));
|
|
6
|
-
const id = encodeBase32LowerCase(bytes);
|
|
7
|
-
return id;
|
|
8
|
-
}
|
|
9
|
-
export function generateToken() {
|
|
10
|
-
const bytes = crypto.getRandomValues(new Uint8Array(18));
|
|
11
|
-
const token = encodeBase64url(bytes);
|
|
12
|
-
return token;
|
|
13
|
-
}
|
|
14
|
-
export function encodeToken(token) {
|
|
15
|
-
const sessionId = encodeHexLowerCase(sha256(new TextEncoder().encode(token)));
|
|
16
|
-
return sessionId;
|
|
17
|
-
}
|
|
18
|
-
export function generateAndEncodeToken() {
|
|
19
|
-
return encodeToken(generateToken());
|
|
20
|
-
}
|
|
21
|
-
export function createDate(timeSpan_seconds, options) {
|
|
22
|
-
const from = options?.from ?? new Date();
|
|
23
|
-
return new Date(from.getTime() + timeSpan_seconds * 1000);
|
|
24
|
-
}
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
export declare function setSessionTokenCookie(token: string, expiresAt: Date): void;
|
|
2
|
-
export declare function deleteSessionTokenCookie(): void;
|
|
3
|
-
export declare function setCodeVerifierCookie(codeVerifier: string): void;
|
|
4
|
-
export declare function setOAuthStateCookie(provider: string, state: string): void;
|
|
5
|
-
export declare function setRedirectCookie(redirect: string): void;
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import { DEV } from 'esm-env';
|
|
2
|
-
import { remult } from 'remult';
|
|
3
|
-
import { getSafeOptions } from './module';
|
|
4
|
-
export function setSessionTokenCookie(token, expiresAt) {
|
|
5
|
-
const oSafe = getSafeOptions();
|
|
6
|
-
if (remult.context.setCookie) {
|
|
7
|
-
remult.context.setCookie(oSafe.session.cookieName, token, {
|
|
8
|
-
expires: expiresAt,
|
|
9
|
-
path: '/',
|
|
10
|
-
});
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
export function deleteSessionTokenCookie() {
|
|
14
|
-
const oSafe = getSafeOptions();
|
|
15
|
-
remult.context.deleteCookie(oSafe.session.cookieName, {
|
|
16
|
-
path: '/',
|
|
17
|
-
});
|
|
18
|
-
}
|
|
19
|
-
export function setCodeVerifierCookie(codeVerifier) {
|
|
20
|
-
remult.context.setCookie('code_verifier', codeVerifier, {
|
|
21
|
-
secure: !DEV,
|
|
22
|
-
path: '/',
|
|
23
|
-
httpOnly: true,
|
|
24
|
-
maxAge: 60 * 10, // 10 min
|
|
25
|
-
});
|
|
26
|
-
}
|
|
27
|
-
export function setOAuthStateCookie(provider, state) {
|
|
28
|
-
remult.context.setCookie(`${provider}_oauth_state`, state, {
|
|
29
|
-
path: '/',
|
|
30
|
-
secure: !DEV,
|
|
31
|
-
httpOnly: true,
|
|
32
|
-
maxAge: 60 * 10,
|
|
33
|
-
sameSite: 'lax',
|
|
34
|
-
});
|
|
35
|
-
}
|
|
36
|
-
export function setRedirectCookie(redirect) {
|
|
37
|
-
remult.context.setCookie(`remult_redirect`, redirect, {
|
|
38
|
-
path: '/',
|
|
39
|
-
secure: !DEV,
|
|
40
|
-
httpOnly: true,
|
|
41
|
-
maxAge: 60 * 10,
|
|
42
|
-
sameSite: 'lax',
|
|
43
|
-
});
|
|
44
|
-
}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { type ClassType } from 'remult';
|
|
2
|
-
import type { Log } from '@kitql/helpers';
|
|
3
|
-
import { type FFAuthAccount, type FFAuthUser } 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 declare const mergeRoles: (existing: string[], newOnes: string[] | undefined) => {
|
|
9
|
-
roles: string[];
|
|
10
|
-
changed: boolean;
|
|
11
|
-
};
|
|
12
|
-
export declare const linkRoleToUsersFromEnv: (o: {
|
|
13
|
-
log: Log;
|
|
14
|
-
accountEntity: ClassType<FFAuthAccount>;
|
|
15
|
-
userEntity: ClassType<FFAuthUser>;
|
|
16
|
-
envKey: string;
|
|
17
|
-
envValue: string;
|
|
18
|
-
roles: string[];
|
|
19
|
-
}) => Promise<void>;
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import { repo } from 'remult';
|
|
2
|
-
import { nameify } from '../../formats';
|
|
3
|
-
import { cyan, green, yellow } from '@kitql/helpers';
|
|
4
|
-
import { FFAuthProvider } from '../Entities';
|
|
5
|
-
/**
|
|
6
|
-
* will merge the roles and remove duplicates
|
|
7
|
-
* will return a new array & a status if the array was changed
|
|
8
|
-
*/
|
|
9
|
-
export const mergeRoles = (existing, newOnes) => {
|
|
10
|
-
const result = new Set(existing);
|
|
11
|
-
let changed = false;
|
|
12
|
-
for (const role of newOnes ?? []) {
|
|
13
|
-
if (!result.has(role)) {
|
|
14
|
-
result.add(role);
|
|
15
|
-
changed = true;
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
return { roles: Array.from(result), changed };
|
|
19
|
-
};
|
|
20
|
-
export const linkRoleToUsersFromEnv = async (o) => {
|
|
21
|
-
const { log, accountEntity, userEntity, envKey, envValue, roles } = o;
|
|
22
|
-
const providersInfo = envValue === undefined
|
|
23
|
-
? []
|
|
24
|
-
: (envValue ?? '')
|
|
25
|
-
.split(',')
|
|
26
|
-
.map((c) => c.trim())
|
|
27
|
-
.filter(Boolean);
|
|
28
|
-
for (let i = 0; i < providersInfo.length; i++) {
|
|
29
|
-
const [providerUserId, provider] = providersInfo[i].split('|');
|
|
30
|
-
let a = await repo(accountEntity).findFirst({ providerUserId });
|
|
31
|
-
if (!a) {
|
|
32
|
-
const user = await repo(userEntity).upsert({ where: { roles, name: nameify(providerUserId) } });
|
|
33
|
-
a = await repo(accountEntity).insert({
|
|
34
|
-
providerUserId,
|
|
35
|
-
provider: provider ?? FFAuthProvider.PASSWORD.id,
|
|
36
|
-
userId: user.id,
|
|
37
|
-
});
|
|
38
|
-
}
|
|
39
|
-
else {
|
|
40
|
-
let user = await repo(userEntity).findFirst({ id: a.userId });
|
|
41
|
-
if (!user) {
|
|
42
|
-
user = repo(userEntity).create({ id: a.userId, name: nameify(providerUserId) });
|
|
43
|
-
}
|
|
44
|
-
const newRoles = [...new Set([...user.roles, ...roles].sort())];
|
|
45
|
-
if ((newRoles ?? []).join(',') !== (user.roles ?? []).join(',')) {
|
|
46
|
-
user.roles = newRoles;
|
|
47
|
-
await repo(userEntity).save(user);
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
if (providersInfo.length > 0) {
|
|
52
|
-
log.info(`${cyan(envKey)}: ${providersInfo.map((c) => green(c.trim())).join(', ')} added via ${yellow(`.env`)}.`);
|
|
53
|
-
}
|
|
54
|
-
else {
|
|
55
|
-
log.info(`${cyan(envKey)}: No users added via ${yellow(`.env`)}.`);
|
|
56
|
-
}
|
|
57
|
-
};
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import * as arctic from 'arctic';
|
|
2
|
-
import { handleAuth } from './handleAuth.js';
|
|
3
|
-
import { handleGuard } from './handleGuard.js';
|
|
4
|
-
export { auth, authModuleRaw } from './module';
|
|
5
|
-
export { linkRoleToUsersFromEnv as initRoleFromEnv } from './helperRole';
|
|
6
|
-
export { checkOAuthConfig } from './providers/helperProvider';
|
|
7
|
-
export { github } from './providers/github';
|
|
8
|
-
export { arctic, handleAuth, handleGuard };
|
package/esm/auth/server/index.js
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import * as arctic from 'arctic';
|
|
2
|
-
import { handleAuth } from './handleAuth.js';
|
|
3
|
-
import { handleGuard } from './handleGuard.js';
|
|
4
|
-
export { auth, authModuleRaw } from './module';
|
|
5
|
-
export { linkRoleToUsersFromEnv as initRoleFromEnv } from './helperRole';
|
|
6
|
-
export { checkOAuthConfig } from './providers/helperProvider';
|
|
7
|
-
export { github } from './providers/github';
|
|
8
|
-
export { arctic, handleAuth, handleGuard };
|
|
@@ -1,300 +0,0 @@
|
|
|
1
|
-
import type { OAuth2Tokens } from 'arctic';
|
|
2
|
-
import type { ClassType, UserInfo } from 'remult';
|
|
3
|
-
import { ModuleFF } from '../../server';
|
|
4
|
-
import type { RecursivePartial } from '../../utils/types';
|
|
5
|
-
import { FFAuthAccount, FFAuthUser, FFAuthUserSession } from '../Entities';
|
|
6
|
-
import type { FirstlyData, FirstlyDataAuth, OAuth2UserInfo, ProviderAuthorizationURLOptions } from '../types';
|
|
7
|
-
export type FFOAuth2Provider<T = any, LitName extends string = string> = {
|
|
8
|
-
name: LitName;
|
|
9
|
-
caption: string;
|
|
10
|
-
raw_svg?: string;
|
|
11
|
-
getArcticProvider: () => T;
|
|
12
|
-
authorizationURLOptions: () => ProviderAuthorizationURLOptions;
|
|
13
|
-
getUserInfo(tokens: OAuth2Tokens): Promise<OAuth2UserInfo>;
|
|
14
|
-
};
|
|
15
|
-
type AuthOptions<TUserEntity extends FFAuthUser = FFAuthUser, TSessionEntity extends FFAuthUserSession = FFAuthUserSession, TAccountEntity extends FFAuthAccount = FFAuthAccount> = {
|
|
16
|
-
customEntities?: {
|
|
17
|
-
User?: ClassType<TUserEntity>;
|
|
18
|
-
Session?: ClassType<TSessionEntity>;
|
|
19
|
-
Account?: ClassType<TAccountEntity>;
|
|
20
|
-
};
|
|
21
|
-
debug?: boolean;
|
|
22
|
-
ui?: false | RecursivePartial<FirstlyDataAuth['ui']>;
|
|
23
|
-
strings?: {
|
|
24
|
-
resetPasswordSend?: string;
|
|
25
|
-
resetPasswordUnknownUser?: string;
|
|
26
|
-
anErrorOccurred?: string;
|
|
27
|
-
cannotSignUp?: string;
|
|
28
|
-
};
|
|
29
|
-
/** Usefull to overwrite where the static files are */
|
|
30
|
-
uiStaticPath?: string;
|
|
31
|
-
session?: {
|
|
32
|
-
/** in milliseconds @default 30 days (1000 * 60 * 60 * 24 * 30) */
|
|
33
|
-
expiresIn?: number;
|
|
34
|
-
COOKIE_NAME?: string;
|
|
35
|
-
};
|
|
36
|
-
defaultRedirect?: string;
|
|
37
|
-
/**
|
|
38
|
-
* Can a user sign up by itself? Or we can join only by invitation ?
|
|
39
|
-
* If false, no one can sign up alone.
|
|
40
|
-
* @default true
|
|
41
|
-
**/
|
|
42
|
-
signUp?: boolean;
|
|
43
|
-
/**
|
|
44
|
-
* To be able to sign in user needs to be verified or not?
|
|
45
|
-
* ```
|
|
46
|
-
* `Auto` => noting will be checked
|
|
47
|
-
* `Email` => users needs to click a link in an email
|
|
48
|
-
* `Manual` => an admin needs to verify the user and set verifiedAt in the database
|
|
49
|
-
* ```
|
|
50
|
-
* @default auto
|
|
51
|
-
**/
|
|
52
|
-
verifiedMethod?: 'auto' | 'email' | 'manual';
|
|
53
|
-
invitationSend?: (args: {
|
|
54
|
-
email: string;
|
|
55
|
-
url: string;
|
|
56
|
-
}) => Promise<void>;
|
|
57
|
-
/**
|
|
58
|
-
* When defining this, you need to return a "manually constructed object" that will be used to send to the client.
|
|
59
|
-
* This is useful if you want to add some extra properties to the user object.
|
|
60
|
-
*
|
|
61
|
-
* @example
|
|
62
|
-
* ```ts
|
|
63
|
-
* transformDbUserToClientUser(session, user) {
|
|
64
|
-
* return {
|
|
65
|
-
* id: user.id,
|
|
66
|
-
* name: user.name,
|
|
67
|
-
* image: user.image ?? undefined,
|
|
68
|
-
* session: {
|
|
69
|
-
* id: session.id,
|
|
70
|
-
* expiresAt: session.expiresAt,
|
|
71
|
-
* },
|
|
72
|
-
* }
|
|
73
|
-
* }
|
|
74
|
-
* ```
|
|
75
|
-
*/
|
|
76
|
-
transformDbUserToClientUser?: (session: TSessionEntity, user: TUserEntity) => UserInfo;
|
|
77
|
-
providers?: {
|
|
78
|
-
demo?: {
|
|
79
|
-
name: string;
|
|
80
|
-
roles?: string[];
|
|
81
|
-
}[];
|
|
82
|
-
password?: {
|
|
83
|
-
mail?: {
|
|
84
|
-
reset?: {
|
|
85
|
-
send?: (args: {
|
|
86
|
-
email: string;
|
|
87
|
-
url: string;
|
|
88
|
-
}) => Promise<void>;
|
|
89
|
-
/** in secondes @default 5 minutes */
|
|
90
|
-
expiresIn?: number;
|
|
91
|
-
};
|
|
92
|
-
verify?: {
|
|
93
|
-
send?: (args: {
|
|
94
|
-
email: string;
|
|
95
|
-
url: string;
|
|
96
|
-
}) => Promise<void>;
|
|
97
|
-
/** in secondes @default 5 minutes */
|
|
98
|
-
expiresIn?: number;
|
|
99
|
-
};
|
|
100
|
-
};
|
|
101
|
-
algo?: {
|
|
102
|
-
/**
|
|
103
|
-
* Validate the password or throw an error.
|
|
104
|
-
*
|
|
105
|
-
* Here is an example (and it's the default implementation):
|
|
106
|
-
* ```
|
|
107
|
-
* function validatePassword(password: string) {
|
|
108
|
-
* if (typeof password !== 'string' || password.length < 6 || password.length > 255) {
|
|
109
|
-
* throw new EntityError({ message: 'Invalid password' })
|
|
110
|
-
* }
|
|
111
|
-
* }
|
|
112
|
-
* ```
|
|
113
|
-
*/
|
|
114
|
-
validateInput?: ({ identifier, password }: {
|
|
115
|
-
identifier: string;
|
|
116
|
-
password: string;
|
|
117
|
-
}) => void;
|
|
118
|
-
/**
|
|
119
|
-
* If you want to NOT use the default bcrypt, you can pass your own thing!
|
|
120
|
-
*/
|
|
121
|
-
hash?: (password: string) => Promise<string>;
|
|
122
|
-
/**
|
|
123
|
-
* If you want to NOT use the default bcrypt, you can pass your own thing!
|
|
124
|
-
*/
|
|
125
|
-
verify?: (password: string, hash: string) => Promise<boolean>;
|
|
126
|
-
bcrypt?: {
|
|
127
|
-
/**
|
|
128
|
-
* The number of rounds to use for the bcrypt hash.
|
|
129
|
-
* @default 10
|
|
130
|
-
*/
|
|
131
|
-
saltRounds?: number;
|
|
132
|
-
};
|
|
133
|
-
};
|
|
134
|
-
};
|
|
135
|
-
otp?: {
|
|
136
|
-
issuer?: string;
|
|
137
|
-
/** in secondes @default 30 seconds */
|
|
138
|
-
expiresIn?: number;
|
|
139
|
-
/** Number of digits @default 6 */
|
|
140
|
-
digits?: number;
|
|
141
|
-
send?: (data: {
|
|
142
|
-
name: string;
|
|
143
|
-
otp: string;
|
|
144
|
-
uri: string;
|
|
145
|
-
}) => Promise<void>;
|
|
146
|
-
};
|
|
147
|
-
oAuths?: FFOAuth2Provider[];
|
|
148
|
-
};
|
|
149
|
-
envRoles_AssignUsers?: Record<string, string>;
|
|
150
|
-
};
|
|
151
|
-
export declare let AUTH_OPTIONS: AuthOptions;
|
|
152
|
-
export declare const getSafeOptions: <TUserEntity extends FFAuthUser = FFAuthUser, TSessionEntity extends FFAuthUserSession = FFAuthUserSession, TAccountEntity extends FFAuthAccount = FFAuthAccount>() => {
|
|
153
|
-
User: ClassType<TUserEntity>;
|
|
154
|
-
Session: ClassType<TSessionEntity>;
|
|
155
|
-
Account: ClassType<TAccountEntity>;
|
|
156
|
-
signUp: boolean;
|
|
157
|
-
password: {
|
|
158
|
-
enabled: boolean;
|
|
159
|
-
validateInput: ({ identifier, password }: {
|
|
160
|
-
identifier: string;
|
|
161
|
-
password: string;
|
|
162
|
-
}) => void;
|
|
163
|
-
hash: ((password: string) => Promise<string>) | ((password: string) => string);
|
|
164
|
-
verify: ((password: string, hash: string) => Promise<boolean>) | ((password: string, hash: string) => boolean);
|
|
165
|
-
};
|
|
166
|
-
otp: {
|
|
167
|
-
enabled: boolean;
|
|
168
|
-
};
|
|
169
|
-
verifiedMethod: "email" | "auto" | "manual";
|
|
170
|
-
redirectUrl: string;
|
|
171
|
-
firstlyData: FirstlyData;
|
|
172
|
-
transformDbUserToClientUser: (session: TSessionEntity, user: TUserEntity) => UserInfo;
|
|
173
|
-
uiStaticPath: string;
|
|
174
|
-
session: {
|
|
175
|
-
expiresInMs: number;
|
|
176
|
-
cookieName: string;
|
|
177
|
-
};
|
|
178
|
-
providers: {
|
|
179
|
-
demo?: {
|
|
180
|
-
name: string;
|
|
181
|
-
roles?: string[];
|
|
182
|
-
}[];
|
|
183
|
-
password?: {
|
|
184
|
-
mail?: {
|
|
185
|
-
reset?: {
|
|
186
|
-
send?: (args: {
|
|
187
|
-
email: string;
|
|
188
|
-
url: string;
|
|
189
|
-
}) => Promise<void>;
|
|
190
|
-
/** in secondes @default 5 minutes */
|
|
191
|
-
expiresIn?: number;
|
|
192
|
-
};
|
|
193
|
-
verify?: {
|
|
194
|
-
send?: (args: {
|
|
195
|
-
email: string;
|
|
196
|
-
url: string;
|
|
197
|
-
}) => Promise<void>;
|
|
198
|
-
/** in secondes @default 5 minutes */
|
|
199
|
-
expiresIn?: number;
|
|
200
|
-
};
|
|
201
|
-
};
|
|
202
|
-
algo?: {
|
|
203
|
-
/**
|
|
204
|
-
* Validate the password or throw an error.
|
|
205
|
-
*
|
|
206
|
-
* Here is an example (and it's the default implementation):
|
|
207
|
-
* ```
|
|
208
|
-
* function validatePassword(password: string) {
|
|
209
|
-
* if (typeof password !== 'string' || password.length < 6 || password.length > 255) {
|
|
210
|
-
* throw new EntityError({ message: 'Invalid password' })
|
|
211
|
-
* }
|
|
212
|
-
* }
|
|
213
|
-
* ```
|
|
214
|
-
*/
|
|
215
|
-
validateInput?: ({ identifier, password }: {
|
|
216
|
-
identifier: string;
|
|
217
|
-
password: string;
|
|
218
|
-
}) => void;
|
|
219
|
-
/**
|
|
220
|
-
* If you want to NOT use the default bcrypt, you can pass your own thing!
|
|
221
|
-
*/
|
|
222
|
-
hash?: (password: string) => Promise<string>;
|
|
223
|
-
/**
|
|
224
|
-
* If you want to NOT use the default bcrypt, you can pass your own thing!
|
|
225
|
-
*/
|
|
226
|
-
verify?: (password: string, hash: string) => Promise<boolean>;
|
|
227
|
-
bcrypt?: {
|
|
228
|
-
/**
|
|
229
|
-
* The number of rounds to use for the bcrypt hash.
|
|
230
|
-
* @default 10
|
|
231
|
-
*/
|
|
232
|
-
saltRounds?: number;
|
|
233
|
-
};
|
|
234
|
-
};
|
|
235
|
-
};
|
|
236
|
-
otp?: {
|
|
237
|
-
issuer?: string;
|
|
238
|
-
/** in secondes @default 30 seconds */
|
|
239
|
-
expiresIn?: number;
|
|
240
|
-
/** Number of digits @default 6 */
|
|
241
|
-
digits?: number;
|
|
242
|
-
send?: (data: {
|
|
243
|
-
name: string;
|
|
244
|
-
otp: string;
|
|
245
|
-
uri: string;
|
|
246
|
-
}) => Promise<void>;
|
|
247
|
-
};
|
|
248
|
-
oAuths?: FFOAuth2Provider[];
|
|
249
|
-
} | undefined;
|
|
250
|
-
strings: {
|
|
251
|
-
resetPasswordSend: string;
|
|
252
|
-
resetPasswordUnknownUser: string;
|
|
253
|
-
anErrorOccurred: string;
|
|
254
|
-
cannotSignUp: string;
|
|
255
|
-
};
|
|
256
|
-
ui: {
|
|
257
|
-
readonly paths: {
|
|
258
|
-
readonly base: string;
|
|
259
|
-
readonly sign_up: string | false;
|
|
260
|
-
readonly sign_in: string | false;
|
|
261
|
-
readonly forgot_password: string | false;
|
|
262
|
-
readonly reset_password: string | false;
|
|
263
|
-
readonly verify_email: string | false;
|
|
264
|
-
};
|
|
265
|
-
readonly strings: {
|
|
266
|
-
readonly app_name: string;
|
|
267
|
-
readonly email: string;
|
|
268
|
-
readonly email_placeholder: string;
|
|
269
|
-
readonly password: string;
|
|
270
|
-
readonly password_placeholder: string;
|
|
271
|
-
readonly confirm: string;
|
|
272
|
-
readonly reset: string;
|
|
273
|
-
readonly btn_sign_up: string;
|
|
274
|
-
readonly btn_sign_in: string;
|
|
275
|
-
readonly forgot_password: string;
|
|
276
|
-
readonly send_password_reset_instructions: string;
|
|
277
|
-
readonly back_to_sign_in: string;
|
|
278
|
-
};
|
|
279
|
-
readonly images: {
|
|
280
|
-
readonly main: string;
|
|
281
|
-
};
|
|
282
|
-
readonly customHtmlHead: string;
|
|
283
|
-
} | undefined;
|
|
284
|
-
envRoles_AssignUsers: Record<string, string>;
|
|
285
|
-
};
|
|
286
|
-
export declare const authModuleRaw: ModuleFF;
|
|
287
|
-
/**
|
|
288
|
-
* To enable authentication in your app in a few lines of code.
|
|
289
|
-
* _Info: index: -777_
|
|
290
|
-
*/
|
|
291
|
-
export declare const auth: <TUserEntity extends FFAuthUser = FFAuthUser, TSessionEntity extends FFAuthUserSession = FFAuthUserSession, TAccountEntity extends FFAuthAccount = FFAuthAccount>(o: AuthOptions<TUserEntity, TSessionEntity, TAccountEntity>) => ModuleFF;
|
|
292
|
-
declare module 'remult' {
|
|
293
|
-
interface UserInfo {
|
|
294
|
-
session: {
|
|
295
|
-
id: string;
|
|
296
|
-
expiresAt: Date;
|
|
297
|
-
};
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
export {};
|