@functionalcms/svelte-components 2.19.4 → 2.20.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,2 +1,3 @@
1
1
  import { type Handle } from '@sveltejs/kit';
2
- export declare const authenticationHandle: (scope?: string, redirectPath?: string) => Handle;
2
+ import type { IProvider } from './types.js';
3
+ export declare const authenticationHandle: (provider: IProvider) => Handle;
@@ -1,8 +1,5 @@
1
- import { AUTH_KEYCLOAK_ID, AUTH_KEYCLOAK_ISSUER } from '$env/static/private';
2
1
  import {} from '@sveltejs/kit';
3
2
  import { createSession, getSession, deleteSession } from './sessionStorage.js';
4
- import { keycloak } from './authenticationProvider.js';
5
- const authStateCookieName = `auth_state`;
6
3
  const authSessionCookieName = `auth_session`;
7
4
  const logout = (cookies, afterLogoutPath = '/') => {
8
5
  const headers = new Headers();
@@ -47,8 +44,7 @@ const loadUserFromSession = (cookies, locals) => {
47
44
  locals.username = "";
48
45
  }
49
46
  };
50
- export const authenticationHandle = (scope = '', redirectPath = '/') => {
51
- const provider = keycloak(AUTH_KEYCLOAK_ISSUER, AUTH_KEYCLOAK_ID, scope, redirectPath);
47
+ export const authenticationHandle = (provider) => {
52
48
  return async ({ event, resolve }) => {
53
49
  //login user check + refresh
54
50
  if (event.url.pathname.startsWith('/')) {
@@ -1,5 +1,5 @@
1
1
  import type { Token } from './types.js';
2
- export declare const keycloak: (issuer: string, clientId: string, scope?: string, redirectPath?: string) => {
2
+ export declare const keycloak: (scope?: string, redirectPath?: string) => {
3
3
  getAuthIdentity: (domain: string) => Promise<any>;
4
4
  getValidation: (event: any) => Promise<Token>;
5
5
  getUser: (token: Token) => Promise<any>;
@@ -0,0 +1,86 @@
1
+ import { AUTH_KEYCLOAK_ID, AUTH_KEYCLOAK_SECRET, AUTH_KEYCLOAK_ISSUER } from '$env/static/private';
2
+ import * as o from "oauth4webapi";
3
+ const authStateCookieName = 'auth_state';
4
+ const stateIdGenerator = () => crypto.randomUUID();
5
+ const getKeycloakIdentity = async (issuer, client_id, scope, redirectUrl) => {
6
+ const state = stateIdGenerator();
7
+ const cookieHeader = `${authStateCookieName}=${state}; HttpOnly; Secure; SameSite=Lax; Max-Age=3600; Path=/`;
8
+ // const code_challenge = await o.calculatePKCECodeChallenge(state);
9
+ // const authorizationUrlSearchParams = new URLSearchParams({
10
+ // client_id: client_id,
11
+ // redirect_uri: redirectUrl,
12
+ // response_type: 'code',
13
+ // state,
14
+ // scope,
15
+ // code_challenge
16
+ // });
17
+ // const authorizationUrl = `${issuer}/protocol/openid-connect/auth?${authorizationUrlSearchParams}`;
18
+ const headers = new Headers();
19
+ // headers.append('Set-Cookie', cookieHeader);
20
+ headers.append('Location', '/auth/validate');
21
+ return headers;
22
+ };
23
+ const getKeycloakValidation = async (issuer, client_id, client_secret, scope, event) => {
24
+ const response = await fetch(`${issuer}/protocol/openid-connect/token`, {
25
+ method: "POST",
26
+ body: new URLSearchParams({
27
+ grant_type: "client_credentials",
28
+ client_id: client_id,
29
+ client_secret: client_secret,
30
+ scope,
31
+ }),
32
+ headers: {
33
+ "Content-Type": "application/x-www-form-urlencoded",
34
+ Accept: "application/json"
35
+ }
36
+ });
37
+ if (!response.ok) {
38
+ console.log('Response was NOT okay');
39
+ throw new Error('Token not validated.');
40
+ }
41
+ const token = await response.json();
42
+ return token;
43
+ };
44
+ const getUser = async (issuer, token) => {
45
+ try {
46
+ const accessToken = token.access_token;
47
+ const response = await fetch(`${issuer}/protocol/openid-connect/userinfo`, {
48
+ method: "POST",
49
+ headers: {
50
+ "Content-Type": "application/x-www-form-urlencoded",
51
+ Accept: "application/json",
52
+ Authorization: `Bearer ${accessToken}`
53
+ }
54
+ });
55
+ if (!response.ok) {
56
+ throw new Error('Failed to fetch user information.');
57
+ }
58
+ const data = await response.json();
59
+ return data;
60
+ }
61
+ catch (error) {
62
+ return new Response(null, {
63
+ status: 400
64
+ });
65
+ }
66
+ };
67
+ export const keycloak = (scope = '', redirectPath = '/') => {
68
+ const extendedScope = `openid profile offline_access ${scope}`;
69
+ const redirectUrl = "/auth/validate";
70
+ return {
71
+ getAuthIdentity: async (domain) => {
72
+ const provider = await getKeycloakIdentity(AUTH_KEYCLOAK_ISSUER, AUTH_KEYCLOAK_ID, extendedScope, `${domain}${redirectUrl}`);
73
+ return provider;
74
+ },
75
+ getValidation: async (event) => {
76
+ const fullRedirectUrl = `${event.url.origin}${redirectUrl}`;
77
+ const token = await getKeycloakValidation(AUTH_KEYCLOAK_ISSUER, AUTH_KEYCLOAK_ID, AUTH_KEYCLOAK_SECRET, extendedScope, event);
78
+ return token;
79
+ },
80
+ getUser: async (token) => {
81
+ const user = await getUser(AUTH_KEYCLOAK_ISSUER, token);
82
+ return user;
83
+ },
84
+ redirectPath
85
+ };
86
+ };
@@ -0,0 +1,7 @@
1
+ import type { Token } from './types.js';
2
+ export declare const userAuthenticationProvider: (scope?: string, redirectPath?: string) => {
3
+ getAuthIdentity: (domain: string) => Promise<any>;
4
+ getValidation: (event: any) => Promise<Token>;
5
+ getUser: (token: Token) => Promise<any>;
6
+ redirectPath: string;
7
+ };
@@ -1,3 +1,4 @@
1
+ import { AUTH_KEYCLOAK_ID, AUTH_KEYCLOAK_ISSUER } from '$env/static/private';
1
2
  import * as o from "oauth4webapi";
2
3
  const authStateCookieName = 'auth_state';
3
4
  const stateIdGenerator = () => crypto.randomUUID();
@@ -75,21 +76,21 @@ const getUser = async (issuer, token) => {
75
76
  });
76
77
  }
77
78
  };
78
- export const keycloak = (issuer, clientId, scope = '', redirectPath = '/') => {
79
+ export const userAuthenticationProvider = (scope = '', redirectPath = '/') => {
79
80
  const extendedScope = `openid profile offline_access ${scope}`;
80
81
  const redirectUrl = "/auth/validate";
81
82
  return {
82
83
  getAuthIdentity: async (domain) => {
83
- const provider = await getKeycloakIdentity(issuer, clientId, extendedScope, `${domain}${redirectUrl}`);
84
+ const provider = await getKeycloakIdentity(AUTH_KEYCLOAK_ISSUER, AUTH_KEYCLOAK_ID, extendedScope, `${domain}${redirectUrl}`);
84
85
  return provider;
85
86
  },
86
87
  getValidation: async (event) => {
87
88
  const fullRedirectUrl = `${event.url.origin}${redirectUrl}`;
88
- const token = await getKeycloakValidation(issuer, clientId, extendedScope, event, fullRedirectUrl);
89
+ const token = await getKeycloakValidation(AUTH_KEYCLOAK_ISSUER, AUTH_KEYCLOAK_ID, extendedScope, event, fullRedirectUrl);
89
90
  return token;
90
91
  },
91
92
  getUser: async (token) => {
92
- const user = await getUser(issuer, token);
93
+ const user = await getUser(AUTH_KEYCLOAK_ISSUER, token);
93
94
  return user;
94
95
  },
95
96
  redirectPath
@@ -1,14 +1,12 @@
1
1
  <script>import { HeaderNavigationItem } from "./Menu.js";
2
- import { pages as pagesStore } from "../../stores/pages.js";
3
2
  import { selectVisible } from "./MenuFunctions.js";
4
3
  import { isAuthenticated } from "./authentication.js";
5
4
  import { page } from "$app/stores";
6
5
  export let css = "";
7
6
  export let navCss = "";
8
7
  export let localPages = [];
9
- $: activePages = !localPages || localPages.length == 0 ? $pagesStore : localPages;
10
8
  $: pagesVisiblity = isAuthenticated($page);
11
- $: visibleNavItems = selectVisible(activePages, pagesVisiblity);
9
+ $: visibleNavItems = selectVisible(localPages, pagesVisiblity);
12
10
  const klasses = ["flex", "flex-dynamic-row", css ? css : ""].filter((c) => c).join(" ");
13
11
  </script>
14
12
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@functionalcms/svelte-components",
3
- "version": "2.19.4",
3
+ "version": "2.20.0",
4
4
  "watch": {
5
5
  "build": {
6
6
  "patterns": [