@functionalcms/svelte-components 2.21.1 → 2.22.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.
@@ -1,3 +1,3 @@
1
1
  import { type Handle } from '@sveltejs/kit';
2
- import type { IProvider } from './types.js';
3
- export declare const authenticationHandle: (provider: IProvider) => Handle;
2
+ import type { IProvider, ISessionStorage } from './types.js';
3
+ export declare const authenticationHandle: (provider: IProvider, sessionProvider: ISessionStorage) => Handle;
@@ -1,13 +1,12 @@
1
1
  import {} from '@sveltejs/kit';
2
- import { createSession, getSession, deleteSession } from './sessionStorage.js';
3
2
  const authSessionCookieName = `auth_session`;
4
- const logout = async (cookies, afterLogoutPath = '/') => {
3
+ const logout = async (cookies, sessionProvider, afterLogoutPath = '/') => {
5
4
  const headers = new Headers();
6
5
  const state = cookies.get(authSessionCookieName);
7
6
  if (state) {
8
7
  cookies.delete('auth_session', { path: '/' });
9
8
  const sid = cookies.get('auth_session');
10
- deleteSession(sid);
9
+ await sessionProvider.deleteSession(sid);
11
10
  headers.append('Set-Cookie', `${authSessionCookieName}=; Path=/; Expires=Thu, 01 Jan 1970 00:00:00 GMT;`);
12
11
  headers.append('Location', afterLogoutPath);
13
12
  }
@@ -16,7 +15,7 @@ const logout = async (cookies, afterLogoutPath = '/') => {
16
15
  }
17
16
  return headers;
18
17
  };
19
- const createUserSession = async (provider, event) => {
18
+ const createUserSession = async (provider, event, sessionProvider) => {
20
19
  const token = await provider.getValidation(event);
21
20
  const session = await provider.getUser(token);
22
21
  const headers = new Headers();
@@ -24,7 +23,7 @@ const createUserSession = async (provider, event) => {
24
23
  session.userId = session.sub;
25
24
  event.locals.session = session;
26
25
  event.locals.accessToken = token.access_token;
27
- const sessionId = createSession({ session, token }, token.expires_in);
26
+ const sessionId = await sessionProvider.createSession({ session, token }, token.expires_in);
28
27
  headers.append('Location', provider.redirectPath);
29
28
  headers.append('Set-Cookie', `${authSessionCookieName}=${sessionId}; HttpOnly; Secure; SameSite=Lax; Max-Age=3600; Path=/`);
30
29
  // `${authSessionCookieName}=${sessionId}; HttpOnly; Secure; SameSite=Lax; Max-Age=${token.expires_in}; Path=/`);
@@ -34,9 +33,9 @@ const createUserSession = async (provider, event) => {
34
33
  }
35
34
  return headers;
36
35
  };
37
- const loadUserFromSession = (cookies, locals) => {
36
+ const loadUserFromSession = async (cookies, locals, sessionProvider) => {
38
37
  const sid = cookies.get(authSessionCookieName);
39
- const session = getSession(sid);
38
+ const session = await sessionProvider.getSession(sid);
40
39
  if (session) {
41
40
  locals.session = session.session;
42
41
  locals.token = session.token;
@@ -45,16 +44,16 @@ const loadUserFromSession = (cookies, locals) => {
45
44
  locals.username = "";
46
45
  }
47
46
  };
48
- export const authenticationHandle = (provider) => {
47
+ export const authenticationHandle = (provider, sessionProvider) => {
49
48
  return async ({ event, resolve }) => {
50
49
  //login user check + refresh
51
50
  if (event.url.pathname.startsWith('/')) {
52
- loadUserFromSession(event.cookies, event.locals);
51
+ await loadUserFromSession(event.cookies, event.locals, sessionProvider);
53
52
  }
54
53
  //logout
55
54
  if (event.url.pathname === '/auth/logout') {
56
55
  // await provider.logout();
57
- const headers = await logout(event.cookies);
56
+ const headers = await logout(event.cookies, sessionProvider);
58
57
  return new Response('Logging Out...', { status: 303, headers });
59
58
  }
60
59
  // login
@@ -64,7 +63,7 @@ export const authenticationHandle = (provider) => {
64
63
  }
65
64
  //validate
66
65
  else if (event.url.pathname === "/auth/validate") {
67
- const validationResponse = await createUserSession(provider, event);
66
+ const validationResponse = await createUserSession(provider, event, sessionProvider);
68
67
  return new Response('Redirect', { status: 302, headers: validationResponse });
69
68
  }
70
69
  return await resolve(event);
@@ -0,0 +1,12 @@
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 getSession(sid: Sid): Promise<ISession | undefined>;
5
+ declare function deleteSession(sid: string): Promise<void>;
6
+ export declare const inMemorySessionProvider: {
7
+ clean: typeof clean;
8
+ createSession: typeof createSession;
9
+ getSession: typeof getSession;
10
+ deleteSession: typeof deleteSession;
11
+ };
12
+ export {};
@@ -0,0 +1,46 @@
1
+ import { getSid } from './sessionIdGenerator.js';
2
+ const sessionStore = new Map();
3
+ let nextClean = Date.now() + 1000 * 60 * 60; // 1 hour
4
+ async function clean() {
5
+ const now = Date.now();
6
+ for (const [sid, session] of sessionStore) {
7
+ if (session.invalidAt < now) {
8
+ sessionStore.delete(sid);
9
+ }
10
+ }
11
+ // // TODO: delete session from browser storage
12
+ nextClean = Date.now() + 1000 * 60 * 60; // 1 hour
13
+ }
14
+ if (Date.now() > nextClean) {
15
+ //call in setTimeout to not block the server
16
+ setTimeout(() => {
17
+ clean();
18
+ }, 5000);
19
+ }
20
+ async function createSession(session, maxAge) {
21
+ let sid = '';
22
+ do {
23
+ sid = getSid();
24
+ } while (sessionStore.has(sid));
25
+ sessionStore.set(sid, {
26
+ data: session,
27
+ invalidAt: Date.now() + maxAge
28
+ });
29
+ return sid;
30
+ }
31
+ async function getSession(sid) {
32
+ if (sessionStore.has(sid)) {
33
+ const cache = sessionStore.get(sid);
34
+ return cache?.data;
35
+ }
36
+ return undefined;
37
+ }
38
+ async function deleteSession(sid) {
39
+ sessionStore.delete(sid);
40
+ }
41
+ export const inMemorySessionProvider = {
42
+ clean: clean,
43
+ createSession: createSession,
44
+ getSession: getSession,
45
+ deleteSession: deleteSession,
46
+ };
@@ -0,0 +1,12 @@
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 getSession(sid: Sid): Promise<any>;
5
+ declare function deleteSession(sid: string): Promise<void>;
6
+ export declare const redisSessionProvider: {
7
+ clean: typeof clean;
8
+ createSession: typeof createSession;
9
+ getSession: typeof getSession;
10
+ deleteSession: typeof deleteSession;
11
+ };
12
+ export {};
@@ -0,0 +1,36 @@
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
16
+ };
17
+ await redis.set(sid, JSON.stringify(sessionObject));
18
+ return sid;
19
+ }
20
+ async function getSession(sid) {
21
+ const savedSession = await redis.get(sid);
22
+ if (savedSession) {
23
+ const session = JSON.parse(savedSession);
24
+ return session.data;
25
+ }
26
+ return null;
27
+ }
28
+ async function deleteSession(sid) {
29
+ await redis.del(sid);
30
+ }
31
+ export const redisSessionProvider = {
32
+ clean: clean,
33
+ createSession: createSession,
34
+ getSession: getSession,
35
+ deleteSession: deleteSession,
36
+ };
@@ -0,0 +1,2 @@
1
+ import type { Sid } from "./types";
2
+ export declare function getSid(): Sid;
@@ -0,0 +1,3 @@
1
+ export function getSid() {
2
+ return crypto.randomUUID();
3
+ }
@@ -1,11 +1,3 @@
1
- export type SessionInfo = {
2
- username: string;
3
- session: any;
4
- };
5
- export type SessionInfoCache = {
6
- data: any;
7
- invalidAt: number;
8
- };
9
1
  export declare class Token {
10
2
  access_token: string;
11
3
  expires_in: number;
@@ -16,9 +8,24 @@ export declare class Token {
16
8
  session_state?: string;
17
9
  token_type?: string;
18
10
  }
11
+ export type ISession = {
12
+ session: any;
13
+ token: Token;
14
+ };
15
+ export type SessionInfoCache = {
16
+ data: ISession;
17
+ invalidAt: number;
18
+ };
19
+ export type Sid = string;
19
20
  export interface IProvider {
20
21
  redirectPath: string;
21
22
  getAuthIdentity(domain: string): Promise<any>;
22
23
  getValidation(event: any): Promise<Token>;
23
24
  getUser(token: Token): any;
24
25
  }
26
+ export interface ISessionStorage {
27
+ clean(): Promise<void>;
28
+ createSession(session: ISession, maxAge: number): Promise<Sid>;
29
+ getSession(sid: Sid): Promise<ISession | undefined>;
30
+ deleteSession(sid: Sid): Promise<void>;
31
+ }
@@ -1,7 +1,9 @@
1
1
  import { authenticationHandle } from './auth/authenticationHandle.js';
2
2
  import authorizationHandle from './auth/authorizationHandle.js';
3
3
  import errorHandler from './auth/errorHandle.js';
4
+ import { inMemorySessionProvider } from './auth/inMemorySessionProvider.js';
5
+ import { redisSessionProvider } from './auth/redisSessionProvider.js';
4
6
  import { machineAuthenticationProvider } from './auth/machineAuthenticationProvider.js';
5
7
  import { userAuthenticationProvider } from './auth/userAuthenticationProvider.js';
6
8
  import { getBlobService, getCommunicationService, getDataService, getTemplateService, getWebsiteService } from './server-side/getServices.js';
7
- export { authenticationHandle, authorizationHandle, errorHandler, machineAuthenticationProvider, userAuthenticationProvider, getDataService, getCommunicationService, getWebsiteService, getTemplateService, getBlobService };
9
+ export { authenticationHandle, authorizationHandle, errorHandler, machineAuthenticationProvider, userAuthenticationProvider, inMemorySessionProvider, redisSessionProvider, getDataService, getCommunicationService, getWebsiteService, getTemplateService, getBlobService };
@@ -1,7 +1,9 @@
1
1
  import { authenticationHandle } from './auth/authenticationHandle.js';
2
2
  import authorizationHandle from './auth/authorizationHandle.js';
3
3
  import errorHandler from './auth/errorHandle.js';
4
+ import { inMemorySessionProvider } from './auth/inMemorySessionProvider.js';
5
+ import { redisSessionProvider } from './auth/redisSessionProvider.js';
4
6
  import { machineAuthenticationProvider } from './auth/machineAuthenticationProvider.js';
5
7
  import { userAuthenticationProvider } from './auth/userAuthenticationProvider.js';
6
8
  import { getBlobService, getCommunicationService, getDataService, getTemplateService, getWebsiteService } from './server-side/getServices.js';
7
- export { authenticationHandle, authorizationHandle, errorHandler, machineAuthenticationProvider, userAuthenticationProvider, getDataService, getCommunicationService, getWebsiteService, getTemplateService, getBlobService };
9
+ export { authenticationHandle, authorizationHandle, errorHandler, machineAuthenticationProvider, userAuthenticationProvider, inMemorySessionProvider, redisSessionProvider, getDataService, getCommunicationService, getWebsiteService, getTemplateService, getBlobService };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@functionalcms/svelte-components",
3
- "version": "2.21.1",
3
+ "version": "2.22.0",
4
4
  "watch": {
5
5
  "build": {
6
6
  "patterns": [
@@ -1,5 +0,0 @@
1
- type Sid = string;
2
- export declare function createSession(session: any, maxAge: number): string;
3
- export declare function getSession(sid: Sid): any;
4
- export declare function deleteSession(sid: string): void;
5
- export {};
@@ -1,73 +0,0 @@
1
- //in memory session Store
2
- const sessionStore = new Map();
3
- let nextClean = Date.now() + 1000 * 60 * 60; // 1 hour
4
- function getSid() {
5
- return crypto.randomUUID();
6
- }
7
- //loops over all sessions and deletes the ones that are expired.
8
- //We call this function every hour when a session is created
9
- function clean() {
10
- const now = Date.now();
11
- for (const [sid, session] of sessionStore) {
12
- if (session.invalidAt < now) {
13
- sessionStore.delete(sid);
14
- }
15
- }
16
- // // TODO: delete session from browser storage
17
- nextClean = Date.now() + 1000 * 60 * 60; // 1 hour
18
- }
19
- //calls clean() function if it has been over 1 hour to delete expired sessions
20
- if (Date.now() > nextClean) {
21
- //call in setTimeout to not block the server
22
- setTimeout(() => {
23
- clean();
24
- }, 5000);
25
- }
26
- //invoked from makeCookieAndSession on login/nativeAuth.ts
27
- export function createSession(session, maxAge) {
28
- let sid = '';
29
- do {
30
- sid = getSid();
31
- } while (sessionStore.has(sid));
32
- sessionStore.set(sid, {
33
- data: session,
34
- invalidAt: Date.now() + maxAge
35
- });
36
- return sid;
37
- }
38
- //gets session from sessionStore, if not in store, adds to it
39
- export function getSession(sid) {
40
- //if session present in sessionStore
41
- if (sessionStore.has(sid)) {
42
- const cache = sessionStore.get(sid);
43
- return cache?.data;
44
- }
45
- else {
46
- /*
47
- // TODO/ITERATION: get session from browser on frontend and store in session store
48
- // const session = sessionStorage.getItem(username)
49
- // if (session) {
50
- // sessionStore.set(sid, session);
51
- // return session;
52
- // }
53
- */
54
- }
55
- //if no session, return undefined
56
- return undefined;
57
- }
58
- //deletes session from sessionStore
59
- export function deleteSession(sid) {
60
- sessionStore.delete(sid);
61
- /*
62
- // // TODO/ITERATION: remove session from browser storage
63
- // // sessionStorage.removeItem(username);
64
- // // localStorage.removeItem(username);
65
- */
66
- }
67
- /*
68
- // TODO/ITERATION: send back to frontend to store in browser
69
- // export function setBrowserSession(sid: string, username: string) {
70
- // sessionStorage.setItem(username, sid);
71
- // localStorage.setItem(username, sid);
72
- // }
73
- */