@functionalcms/svelte-components 2.26.1 → 2.28.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/dist/auth/authenticationHandle.js +3 -2
- package/dist/auth/machineAuthenticationProvider.d.ts +1 -0
- package/dist/auth/machineAuthenticationProvider.js +20 -0
- package/dist/auth/redisSessionProvider copy.d.ts +14 -0
- package/dist/auth/redisSessionProvider copy.js +45 -0
- package/dist/auth/standardPipeline.d.ts +2 -0
- package/dist/auth/standardPipeline.js +7 -0
- package/dist/auth/tokenRefreshHandle.d.ts +3 -0
- package/dist/auth/tokenRefreshHandle.js +48 -0
- package/dist/auth/types.d.ts +1 -0
- package/dist/auth/userAuthenticationProvider.d.ts +1 -0
- package/dist/auth/userAuthenticationProvider.js +20 -0
- package/dist/index-server.d.ts +2 -0
- package/dist/index-server.js +2 -0
- package/package.json +1 -1
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import {} from '@sveltejs/kit';
|
|
2
2
|
const authSessionCookieName = `auth_session`;
|
|
3
|
-
const logout = async (cookies, sessionProvider, afterLogoutPath = '/') => {
|
|
3
|
+
const logout = async (cookies, token, provider, sessionProvider, afterLogoutPath = '/') => {
|
|
4
4
|
const headers = new Headers();
|
|
5
5
|
const state = cookies.get(authSessionCookieName);
|
|
6
6
|
if (state) {
|
|
7
7
|
cookies.delete('auth_session', { path: '/' });
|
|
8
8
|
const sid = cookies.get('auth_session');
|
|
9
9
|
await sessionProvider.deleteSession(sid);
|
|
10
|
+
await provider.logout(token);
|
|
10
11
|
headers.append('Set-Cookie', `${authSessionCookieName}=; Path=/; Expires=Thu, 01 Jan 1970 00:00:00 GMT;`);
|
|
11
12
|
headers.append('Location', afterLogoutPath);
|
|
12
13
|
}
|
|
@@ -53,7 +54,7 @@ export const authenticationHandle = (provider, sessionProvider) => {
|
|
|
53
54
|
//logout
|
|
54
55
|
if (event.url.pathname === '/auth/logout') {
|
|
55
56
|
// await provider.logout();
|
|
56
|
-
const headers = await logout(event.cookies, sessionProvider);
|
|
57
|
+
const headers = await logout(event.cookies, event.locals.token, provider, sessionProvider);
|
|
57
58
|
return new Response('Logging Out...', { status: 303, headers });
|
|
58
59
|
}
|
|
59
60
|
// login
|
|
@@ -3,5 +3,6 @@ export declare const machineAuthenticationProvider: (scope?: string, redirectPat
|
|
|
3
3
|
getAuthIdentity: (domain: string) => Promise<any>;
|
|
4
4
|
getValidation: (event: any) => Promise<Token>;
|
|
5
5
|
getUser: (token: Token) => Promise<any>;
|
|
6
|
+
logout: (token: Token) => Promise<void>;
|
|
6
7
|
redirectPath: string;
|
|
7
8
|
};
|
|
@@ -63,6 +63,23 @@ const getUser = async (issuer, token) => {
|
|
|
63
63
|
});
|
|
64
64
|
}
|
|
65
65
|
};
|
|
66
|
+
const logout = async (issuer, clientId, token) => {
|
|
67
|
+
const response = await fetch(`${issuer}/protocol/openid-connect/logout`, {
|
|
68
|
+
method: "POST",
|
|
69
|
+
body: new URLSearchParams({
|
|
70
|
+
client_id: clientId,
|
|
71
|
+
access_token: token.access_token,
|
|
72
|
+
}),
|
|
73
|
+
headers: {
|
|
74
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
75
|
+
Accept: "application/json"
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
if (!response.ok) {
|
|
79
|
+
console.log('Response was NOT okay');
|
|
80
|
+
throw new Error('Token not validated.');
|
|
81
|
+
}
|
|
82
|
+
};
|
|
66
83
|
export const machineAuthenticationProvider = (scope = '', redirectPath = '/') => {
|
|
67
84
|
const extendedScope = `openid profile offline_access ${scope}`;
|
|
68
85
|
const redirectUrl = "/auth/validate";
|
|
@@ -80,6 +97,9 @@ export const machineAuthenticationProvider = (scope = '', redirectPath = '/') =>
|
|
|
80
97
|
const user = await getUser(AUTH_KEYCLOAK_ISSUER, token);
|
|
81
98
|
return user;
|
|
82
99
|
},
|
|
100
|
+
logout: async (token) => {
|
|
101
|
+
await logout(AUTH_KEYCLOAK_ISSUER, AUTH_KEYCLOAK_ID, token);
|
|
102
|
+
},
|
|
83
103
|
redirectPath
|
|
84
104
|
};
|
|
85
105
|
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ISession, Sid } from './types.js';
|
|
2
|
+
declare function clean(): Promise<void>;
|
|
3
|
+
declare function createSession(session: ISession, maxAge: number): Promise<string>;
|
|
4
|
+
declare function updateSession(sid: string, session: ISession, maxAge: number): Promise<void>;
|
|
5
|
+
declare function getSession(sid: Sid): Promise<any>;
|
|
6
|
+
declare function deleteSession(sid: string): Promise<void>;
|
|
7
|
+
export declare const redisSessionProvider: {
|
|
8
|
+
clean: typeof clean;
|
|
9
|
+
createSession: typeof createSession;
|
|
10
|
+
getSession: typeof getSession;
|
|
11
|
+
deleteSession: typeof deleteSession;
|
|
12
|
+
updateSession: typeof updateSession;
|
|
13
|
+
};
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { getSid } from './sessionIdGenerator.js';
|
|
2
|
+
import Redis from "ioredis";
|
|
3
|
+
import { CACHE_SECRET } from '$env/static/private';
|
|
4
|
+
const url = "functional.redis.cache.windows.net:6380,password=cfENm4qUceDQ2lE8tl5LFLjg4IVx3F4mIAzCaA12xtg=,ssl=True,abortConnect=False";
|
|
5
|
+
const redis = new Redis(6380, "functional.redis.cache.windows.net", {
|
|
6
|
+
password: CACHE_SECRET,
|
|
7
|
+
tls: true
|
|
8
|
+
});
|
|
9
|
+
async function clean() {
|
|
10
|
+
}
|
|
11
|
+
async function createSession(session, maxAge) {
|
|
12
|
+
const sid = getSid();
|
|
13
|
+
const sessionObject = {
|
|
14
|
+
data: session,
|
|
15
|
+
invalidAt: Date.now() + maxAge + 3600
|
|
16
|
+
};
|
|
17
|
+
await redis.set(sid, JSON.stringify(sessionObject), "EX", maxAge);
|
|
18
|
+
return sid;
|
|
19
|
+
}
|
|
20
|
+
async function updateSession(sid, session, maxAge) {
|
|
21
|
+
await redis.del(sid);
|
|
22
|
+
const sessionObject = {
|
|
23
|
+
data: session,
|
|
24
|
+
invalidAt: Date.now() + maxAge + 3600
|
|
25
|
+
};
|
|
26
|
+
await redis.set(sid, JSON.stringify(sessionObject), "EX", maxAge);
|
|
27
|
+
}
|
|
28
|
+
async function getSession(sid) {
|
|
29
|
+
const savedSession = await redis.get(sid);
|
|
30
|
+
if (savedSession) {
|
|
31
|
+
const session = JSON.parse(savedSession);
|
|
32
|
+
return session.data;
|
|
33
|
+
}
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
async function deleteSession(sid) {
|
|
37
|
+
await redis.del(sid);
|
|
38
|
+
}
|
|
39
|
+
export const redisSessionProvider = {
|
|
40
|
+
clean: clean,
|
|
41
|
+
createSession: createSession,
|
|
42
|
+
getSession: getSession,
|
|
43
|
+
deleteSession: deleteSession,
|
|
44
|
+
updateSession: updateSession
|
|
45
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { sequence } from "@sveltejs/kit/hooks";
|
|
2
|
+
import errorHandler from "./errorHandle.js";
|
|
3
|
+
import { tokenRefreshHandle } from "./tokenRefreshHandle.js";
|
|
4
|
+
import authorizationHandle from "./authorizationHandle.js";
|
|
5
|
+
import { authenticationHandle } from "./authenticationHandle.js";
|
|
6
|
+
import { redisSessionProvider } from "./redisSessionProvider.js";
|
|
7
|
+
export const getStandardHandle = (authProvider) => sequence(errorHandler, authenticationHandle(authProvider, redisSessionProvider), tokenRefreshHandle(redisSessionProvider), authorizationHandle(['/.+']));
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import {} from '@sveltejs/kit';
|
|
2
|
+
import { AUTH_KEYCLOAK_ID, AUTH_KEYCLOAK_SECRET, AUTH_KEYCLOAK_ISSUER } from '$env/static/private';
|
|
3
|
+
const authSessionCookieName = `auth_session`;
|
|
4
|
+
function isTokenExpired(token) {
|
|
5
|
+
const base64Url = token.split(".")[1];
|
|
6
|
+
const base64 = base64Url.replace(/-/g, "+").replace(/_/g, "/");
|
|
7
|
+
const jsonPayload = decodeURIComponent(atob(base64)
|
|
8
|
+
.split("")
|
|
9
|
+
.map(function (c) {
|
|
10
|
+
return "%" + ("00" + c.charCodeAt(0).toString(16)).slice(-2);
|
|
11
|
+
})
|
|
12
|
+
.join(""));
|
|
13
|
+
const { exp } = JSON.parse(jsonPayload);
|
|
14
|
+
const expired = Date.now() >= exp * 1000;
|
|
15
|
+
return expired;
|
|
16
|
+
}
|
|
17
|
+
async function refreshToken(clientId, clientSecret, refresh_token) {
|
|
18
|
+
const response = await fetch(`${AUTH_KEYCLOAK_ISSUER}/protocol/openid-connect/token`, {
|
|
19
|
+
method: "POST",
|
|
20
|
+
body: new URLSearchParams({
|
|
21
|
+
grant_type: "refresh_token",
|
|
22
|
+
client_id: clientId,
|
|
23
|
+
client_secret: clientSecret,
|
|
24
|
+
refresh_token: refresh_token,
|
|
25
|
+
}),
|
|
26
|
+
headers: {
|
|
27
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
28
|
+
Accept: "application/json"
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
const newToken = await response.json();
|
|
32
|
+
return newToken;
|
|
33
|
+
}
|
|
34
|
+
export const tokenRefreshHandle = (sessionProvider) => {
|
|
35
|
+
return async ({ event, resolve }) => {
|
|
36
|
+
const locals = event.locals;
|
|
37
|
+
if (locals?.token?.refresh_token) {
|
|
38
|
+
const isExpired = isTokenExpired(locals.token.access_token);
|
|
39
|
+
if (isExpired) {
|
|
40
|
+
const newToken = await refreshToken(AUTH_KEYCLOAK_ID, AUTH_KEYCLOAK_SECRET, locals.token.refresh_token);
|
|
41
|
+
locals.token = newToken;
|
|
42
|
+
const sid = event.cookies.get(authSessionCookieName);
|
|
43
|
+
sessionProvider.updateSession(sid, locals, newToken.expires_in);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return await resolve(event);
|
|
47
|
+
};
|
|
48
|
+
};
|
package/dist/auth/types.d.ts
CHANGED
|
@@ -22,6 +22,7 @@ export interface IProvider {
|
|
|
22
22
|
getAuthIdentity(domain: string): Promise<any>;
|
|
23
23
|
getValidation(event: any): Promise<Token>;
|
|
24
24
|
getUser(token: Token): any;
|
|
25
|
+
logout(token: Token): Promise<any>;
|
|
25
26
|
}
|
|
26
27
|
export interface ISessionStorage {
|
|
27
28
|
clean(): Promise<void>;
|
|
@@ -3,5 +3,6 @@ export declare const userAuthenticationProvider: (scope?: string, redirectPath?:
|
|
|
3
3
|
getAuthIdentity: (domain: string) => Promise<any>;
|
|
4
4
|
getValidation: (event: any) => Promise<Token>;
|
|
5
5
|
getUser: (token: Token) => Promise<any>;
|
|
6
|
+
logout: (token: Token) => Promise<void>;
|
|
6
7
|
redirectPath: string;
|
|
7
8
|
};
|
|
@@ -76,6 +76,23 @@ const getUser = async (issuer, token) => {
|
|
|
76
76
|
});
|
|
77
77
|
}
|
|
78
78
|
};
|
|
79
|
+
const logout = async (issuer, clientId, token) => {
|
|
80
|
+
const response = await fetch(`${issuer}/protocol/openid-connect/logout`, {
|
|
81
|
+
method: "POST",
|
|
82
|
+
body: new URLSearchParams({
|
|
83
|
+
client_id: clientId,
|
|
84
|
+
access_token: token.access_token,
|
|
85
|
+
}),
|
|
86
|
+
headers: {
|
|
87
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
88
|
+
Accept: "application/json"
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
if (!response.ok) {
|
|
92
|
+
console.log('Response was NOT okay');
|
|
93
|
+
throw new Error('Token not validated.');
|
|
94
|
+
}
|
|
95
|
+
};
|
|
79
96
|
export const userAuthenticationProvider = (scope = '', redirectPath = '/') => {
|
|
80
97
|
const extendedScope = `openid profile offline_access ${scope}`;
|
|
81
98
|
const redirectUrl = "/auth/validate";
|
|
@@ -93,6 +110,9 @@ export const userAuthenticationProvider = (scope = '', redirectPath = '/') => {
|
|
|
93
110
|
const user = await getUser(AUTH_KEYCLOAK_ISSUER, token);
|
|
94
111
|
return user;
|
|
95
112
|
},
|
|
113
|
+
logout: async (token) => {
|
|
114
|
+
await logout(AUTH_KEYCLOAK_ISSUER, AUTH_KEYCLOAK_ID, token);
|
|
115
|
+
},
|
|
96
116
|
redirectPath
|
|
97
117
|
};
|
|
98
118
|
};
|
package/dist/index-server.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
export { authenticationHandle } from './auth/authenticationHandle.js';
|
|
2
2
|
export { default as authorizationHandle } from './auth/authorizationHandle.js';
|
|
3
3
|
export { default as errorHandler } from './auth/errorHandle.js';
|
|
4
|
+
export { tokenRefreshHandle } from './auth/tokenRefreshHandle.js';
|
|
5
|
+
export { getStandardHandle } from './auth/standardPipeline.js';
|
|
4
6
|
export { inMemorySessionProvider } from './auth/inMemorySessionProvider.js';
|
|
5
7
|
export { redisSessionProvider } from './auth/redisSessionProvider.js';
|
|
6
8
|
export { machineAuthenticationProvider } from './auth/machineAuthenticationProvider.js';
|
package/dist/index-server.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
export { authenticationHandle } from './auth/authenticationHandle.js';
|
|
2
2
|
export { default as authorizationHandle } from './auth/authorizationHandle.js';
|
|
3
3
|
export { default as errorHandler } from './auth/errorHandle.js';
|
|
4
|
+
export { tokenRefreshHandle } from './auth/tokenRefreshHandle.js';
|
|
5
|
+
export { getStandardHandle } from './auth/standardPipeline.js';
|
|
4
6
|
export { inMemorySessionProvider } from './auth/inMemorySessionProvider.js';
|
|
5
7
|
export { redisSessionProvider } from './auth/redisSessionProvider.js';
|
|
6
8
|
export { machineAuthenticationProvider } from './auth/machineAuthenticationProvider.js';
|