@multiplatform.one/keycloak 0.7.17 → 1.0.1

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.
Files changed (68) hide show
  1. package/lib/Authenticated.d.mts +2 -3
  2. package/lib/Authenticated.d.ts +2 -3
  3. package/lib/Authenticated.js +4 -4
  4. package/lib/Authenticated.mjs +3 -3
  5. package/lib/apollo.d.mts +7 -0
  6. package/lib/apollo.d.ts +7 -0
  7. package/lib/apollo.js +15 -0
  8. package/lib/apollo.mjs +15 -0
  9. package/lib/chunk-267L3NLO.mjs +53 -0
  10. package/lib/{chunk-NH335CDK.js → chunk-2VGMJ7WP.js} +7 -5
  11. package/lib/{chunk-Y23BWOII.mjs → chunk-3KAZ37SK.mjs} +2 -2
  12. package/lib/{chunk-Y5MS3XVZ.mjs → chunk-5CWGWY74.mjs} +1 -1
  13. package/lib/{chunk-OA5TSQWZ.mjs → chunk-6Q4DC5JX.mjs} +1 -1
  14. package/lib/{chunk-UH4K7HGE.mjs → chunk-7NZPJ2EN.mjs} +6 -8
  15. package/lib/{chunk-2BSUCVXL.js → chunk-K2FTCH55.js} +2 -2
  16. package/lib/{chunk-FU4CT24B.mjs → chunk-KWNIT4G4.mjs} +7 -5
  17. package/lib/{chunk-2BKS6UM5.js → chunk-NCIQ66UP.js} +3 -3
  18. package/lib/{chunk-ZW4GP2I5.js → chunk-NWZCPYQP.js} +5 -7
  19. package/lib/{chunk-X53FOCXA.js → chunk-S5HUGQLF.js} +2 -2
  20. package/lib/{chunk-OZLV3US5.js → chunk-VFQKAKK4.js} +7 -7
  21. package/lib/chunk-VPYXLUMD.js +53 -0
  22. package/lib/{chunk-CGLMLNUS.mjs → chunk-W4PGLIAZ.mjs} +2 -2
  23. package/lib/index.d.mts +3 -1
  24. package/lib/index.d.ts +3 -1
  25. package/lib/index.js +18 -10
  26. package/lib/index.mjs +16 -8
  27. package/lib/keycloak/context.d.mts +2 -2
  28. package/lib/keycloak/context.d.ts +2 -2
  29. package/lib/keycloak/index.d.mts +2 -2
  30. package/lib/keycloak/index.d.ts +2 -2
  31. package/lib/keycloak/index.js +3 -3
  32. package/lib/keycloak/index.mjs +2 -2
  33. package/lib/keycloak/keycloak.d.mts +3 -3
  34. package/lib/keycloak/keycloak.d.ts +3 -3
  35. package/lib/keycloak/keycloak.js +3 -3
  36. package/lib/keycloak/keycloak.mjs +2 -2
  37. package/lib/keycloak/keycloak.native.js +2 -2
  38. package/lib/keycloak/keycloak.native.mjs +1 -1
  39. package/lib/provider/AfterAuth.js +4 -4
  40. package/lib/provider/AfterAuth.mjs +3 -3
  41. package/lib/provider/AuthProvider/AuthProvider.js +5 -5
  42. package/lib/provider/AuthProvider/AuthProvider.mjs +4 -4
  43. package/lib/provider/AuthProvider/AuthProvider.native.js +4 -4
  44. package/lib/provider/AuthProvider/AuthProvider.native.mjs +3 -3
  45. package/lib/provider/AuthProvider/index.js +5 -5
  46. package/lib/provider/AuthProvider/index.mjs +4 -4
  47. package/lib/provider/KeycloakProvider.js +6 -6
  48. package/lib/provider/KeycloakProvider.mjs +5 -5
  49. package/lib/provider/index.js +6 -6
  50. package/lib/provider/index.mjs +5 -5
  51. package/lib/routes.d.mts +6 -7
  52. package/lib/routes.d.ts +6 -7
  53. package/lib/routes.js +23 -23
  54. package/lib/routes.mjs +23 -23
  55. package/lib/session/index.js +2 -2
  56. package/lib/session/index.mjs +1 -1
  57. package/lib/session/session.d.mts +3 -3
  58. package/lib/session/session.d.ts +3 -3
  59. package/lib/session/session.js +2 -2
  60. package/lib/session/session.mjs +1 -1
  61. package/package.json +7 -6
  62. package/src/Authenticated.tsx +2 -4
  63. package/src/apollo.ts +95 -0
  64. package/src/index.ts +1 -0
  65. package/src/keycloak/keycloak.ts +4 -3
  66. package/src/provider/AfterAuth.tsx +1 -1
  67. package/src/routes.ts +40 -38
  68. package/src/session/session.ts +19 -9
package/lib/routes.js CHANGED
@@ -6,21 +6,17 @@ var _chunkP57PW2IIjs = require('./chunk-P57PW2II.js');
6
6
  var _nextauth = require('next-auth');
7
7
  var _jwtdecode = require('jwt-decode');
8
8
  var KeycloakProvider = _chunkP57PW2IIjs.__require.call(void 0, "next-auth/providers/keycloak").default;
9
+ var _nextAuth;
9
10
  var NextAuth = _chunkP57PW2IIjs.__require.call(void 0, "next-auth").default;
10
11
  var NextResponse = _chunkP57PW2IIjs.__require.call(void 0, "next/server").NextResponse;
11
12
  var logger = console;
12
- var _nextAuth;
13
- function createAuthHandler(options = {}) {
14
- const handler = NextAuth(createAuthOptions(options));
15
- return {
16
- GET: handler,
17
- POST: handler
18
- };
13
+ function createAuthHandler(options = createNextAuthOptions()) {
14
+ return NextAuth(options);
19
15
  }
20
- function createLogoutHandler(options = {}) {
16
+ function createLogoutHandler(options = createNextAuthOptions()) {
21
17
  return {
22
18
  async GET() {
23
- const idToken = await _asyncOptionalChain([(await _nextauth.getServerSession.call(void 0, createAuthOptions(options))), 'optionalAccess', async _ => _.idToken]);
19
+ const idToken = await _asyncOptionalChain([(await _nextauth.getServerSession.call(void 0, options)), 'optionalAccess', async _ => _.idToken]);
24
20
  if (idToken) {
25
21
  try {
26
22
  await fetch(
@@ -38,7 +34,7 @@ function createLogoutHandler(options = {}) {
38
34
  }
39
35
  };
40
36
  }
41
- function createAuthOptions(options = {}) {
37
+ function createNextAuthOptions(options = {}) {
42
38
  if (_nextAuth)
43
39
  return _nextAuth;
44
40
  _nextAuth = {
@@ -97,18 +93,21 @@ function createAuthOptions(options = {}) {
97
93
  return _nextAuth;
98
94
  }
99
95
  async function refreshAccessToken(nextToken) {
100
- const res = await fetch(process.env.REFRESH_TOKEN_URL || "", {
101
- method: "POST",
102
- headers: {
103
- "Content-Type": "application/x-www-form-urlencoded"
104
- },
105
- body: new URLSearchParams({
106
- client_id: process.env.KEYCLOAK_CLIENT_ID || "",
107
- client_secret: process.env.KEYCLOAK_CLIENT_SECRET || "",
108
- grant_type: "refresh_token",
109
- refresh_token: nextToken.refreshToken
110
- })
111
- });
96
+ const res = await fetch(
97
+ `${process.env.KEYCLOAK_BASE_URL}/realms/${process.env.KEYCLOAK_REALM || "master"}/protocol/openid-connect/token`,
98
+ {
99
+ method: "POST",
100
+ headers: {
101
+ "Content-Type": "application/x-www-form-urlencoded"
102
+ },
103
+ body: new URLSearchParams({
104
+ client_id: process.env.KEYCLOAK_CLIENT_ID || "",
105
+ client_secret: process.env.KEYCLOAK_CLIENT_SECRET || "",
106
+ grant_type: "refresh_token",
107
+ refresh_token: nextToken.refreshToken
108
+ })
109
+ }
110
+ );
112
111
  const refreshToken = await res.json();
113
112
  if (!res.ok)
114
113
  throw refreshToken;
@@ -124,4 +123,5 @@ async function refreshAccessToken(nextToken) {
124
123
 
125
124
 
126
125
 
127
- exports.createAuthHandler = createAuthHandler; exports.createLogoutHandler = createLogoutHandler;
126
+
127
+ exports.createAuthHandler = createAuthHandler; exports.createLogoutHandler = createLogoutHandler; exports.createNextAuthOptions = createNextAuthOptions;
package/lib/routes.mjs CHANGED
@@ -6,21 +6,17 @@ import {
6
6
  import { getServerSession } from "next-auth";
7
7
  import { jwtDecode } from "jwt-decode";
8
8
  var KeycloakProvider = __require("next-auth/providers/keycloak").default;
9
+ var _nextAuth;
9
10
  var NextAuth = __require("next-auth").default;
10
11
  var NextResponse = __require("next/server").NextResponse;
11
12
  var logger = console;
12
- var _nextAuth;
13
- function createAuthHandler(options = {}) {
14
- const handler = NextAuth(createAuthOptions(options));
15
- return {
16
- GET: handler,
17
- POST: handler
18
- };
13
+ function createAuthHandler(options = createNextAuthOptions()) {
14
+ return NextAuth(options);
19
15
  }
20
- function createLogoutHandler(options = {}) {
16
+ function createLogoutHandler(options = createNextAuthOptions()) {
21
17
  return {
22
18
  async GET() {
23
- const idToken = (await getServerSession(createAuthOptions(options)))?.idToken;
19
+ const idToken = (await getServerSession(options))?.idToken;
24
20
  if (idToken) {
25
21
  try {
26
22
  await fetch(
@@ -38,7 +34,7 @@ function createLogoutHandler(options = {}) {
38
34
  }
39
35
  };
40
36
  }
41
- function createAuthOptions(options = {}) {
37
+ function createNextAuthOptions(options = {}) {
42
38
  if (_nextAuth)
43
39
  return _nextAuth;
44
40
  _nextAuth = {
@@ -97,18 +93,21 @@ function createAuthOptions(options = {}) {
97
93
  return _nextAuth;
98
94
  }
99
95
  async function refreshAccessToken(nextToken) {
100
- const res = await fetch(process.env.REFRESH_TOKEN_URL || "", {
101
- method: "POST",
102
- headers: {
103
- "Content-Type": "application/x-www-form-urlencoded"
104
- },
105
- body: new URLSearchParams({
106
- client_id: process.env.KEYCLOAK_CLIENT_ID || "",
107
- client_secret: process.env.KEYCLOAK_CLIENT_SECRET || "",
108
- grant_type: "refresh_token",
109
- refresh_token: nextToken.refreshToken
110
- })
111
- });
96
+ const res = await fetch(
97
+ `${process.env.KEYCLOAK_BASE_URL}/realms/${process.env.KEYCLOAK_REALM || "master"}/protocol/openid-connect/token`,
98
+ {
99
+ method: "POST",
100
+ headers: {
101
+ "Content-Type": "application/x-www-form-urlencoded"
102
+ },
103
+ body: new URLSearchParams({
104
+ client_id: process.env.KEYCLOAK_CLIENT_ID || "",
105
+ client_secret: process.env.KEYCLOAK_CLIENT_SECRET || "",
106
+ grant_type: "refresh_token",
107
+ refresh_token: nextToken.refreshToken
108
+ })
109
+ }
110
+ );
112
111
  const refreshToken = await res.json();
113
112
  if (!res.ok)
114
113
  throw refreshToken;
@@ -123,5 +122,6 @@ async function refreshAccessToken(nextToken) {
123
122
  }
124
123
  export {
125
124
  createAuthHandler,
126
- createLogoutHandler
125
+ createLogoutHandler,
126
+ createNextAuthOptions
127
127
  };
@@ -2,9 +2,9 @@
2
2
 
3
3
 
4
4
 
5
- var _chunkNH335CDKjs = require('../chunk-NH335CDK.js');
5
+ var _chunk2VGMJ7WPjs = require('../chunk-2VGMJ7WP.js');
6
6
  require('../chunk-P57PW2II.js');
7
7
 
8
8
 
9
9
 
10
- exports.getSession = _chunkNH335CDKjs.getSession; exports.useSession = _chunkNH335CDKjs.useSession;
10
+ exports.getSession = _chunk2VGMJ7WPjs.getSession; exports.useSession = _chunk2VGMJ7WPjs.useSession;
@@ -2,7 +2,7 @@ import "../chunk-OAUYHIWG.mjs";
2
2
  import {
3
3
  getSession,
4
4
  useSession
5
- } from "../chunk-FU4CT24B.mjs";
5
+ } from "../chunk-KWNIT4G4.mjs";
6
6
  import "../chunk-ZFXKCRJC.mjs";
7
7
  export {
8
8
  getSession,
@@ -1,7 +1,7 @@
1
- import { Session as Session$1 } from 'next-auth';
2
- import { SessionContextValue as SessionContextValue$1, UseSessionOptions } from 'next-auth/react';
1
+ import { AuthOptions, Session as Session$1 } from 'next-auth';
2
+ import { GetSessionParams, SessionContextValue as SessionContextValue$1, UseSessionOptions } from 'next-auth/react';
3
3
 
4
- declare function getSession(): Promise<Session | null>;
4
+ declare function getSession(options?: AuthOptions | GetSessionParams, req?: any, res?: any): Promise<Session | null>;
5
5
  type SessionContextValue<R extends boolean> = Partial<Omit<SessionContextValue$1<R> & {
6
6
  session: Session;
7
7
  }, 'data'>>;
@@ -1,7 +1,7 @@
1
- import { Session as Session$1 } from 'next-auth';
2
- import { SessionContextValue as SessionContextValue$1, UseSessionOptions } from 'next-auth/react';
1
+ import { AuthOptions, Session as Session$1 } from 'next-auth';
2
+ import { GetSessionParams, SessionContextValue as SessionContextValue$1, UseSessionOptions } from 'next-auth/react';
3
3
 
4
- declare function getSession(): Promise<Session | null>;
4
+ declare function getSession(options?: AuthOptions | GetSessionParams, req?: any, res?: any): Promise<Session | null>;
5
5
  type SessionContextValue<R extends boolean> = Partial<Omit<SessionContextValue$1<R> & {
6
6
  session: Session;
7
7
  }, 'data'>>;
@@ -1,9 +1,9 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
2
 
3
3
 
4
- var _chunkNH335CDKjs = require('../chunk-NH335CDK.js');
4
+ var _chunk2VGMJ7WPjs = require('../chunk-2VGMJ7WP.js');
5
5
  require('../chunk-P57PW2II.js');
6
6
 
7
7
 
8
8
 
9
- exports.getSession = _chunkNH335CDKjs.getSession; exports.useSession = _chunkNH335CDKjs.useSession;
9
+ exports.getSession = _chunk2VGMJ7WPjs.getSession; exports.useSession = _chunk2VGMJ7WPjs.useSession;
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  getSession,
3
3
  useSession
4
- } from "../chunk-FU4CT24B.mjs";
4
+ } from "../chunk-KWNIT4G4.mjs";
5
5
  import "../chunk-ZFXKCRJC.mjs";
6
6
  export {
7
7
  getSession,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@multiplatform.one/keycloak",
3
- "version": "0.7.17",
3
+ "version": "1.0.1",
4
4
  "description": "keycloak client for multiplatform.one ecosystem",
5
5
  "main": "lib/index.js",
6
6
  "module": "lib/index.mjs",
@@ -42,7 +42,7 @@
42
42
  "peerDependencies": {
43
43
  "@react-native-async-storage/async-storage": "1.19.3",
44
44
  "expo-keycloak-auth": "1.0.14",
45
- "multiplatform.one": "^1.0.0",
45
+ "multiplatform.one": "^1.0.2",
46
46
  "next": "^13.0.5",
47
47
  "react": "^18.2.0",
48
48
  "react-native": "~0.73.1"
@@ -54,16 +54,16 @@
54
54
  "@types/jest": "^29.5.11",
55
55
  "@types/lodash.camelcase": "^4.3.9",
56
56
  "@types/lodash.startcase": "^4.4.9",
57
- "@types/react": "^18.2.47",
57
+ "@types/react": "^18.2.48",
58
58
  "@types/react-native": "^0.73.0",
59
59
  "cspell": "^8.3.2",
60
60
  "eslint": "^8.56.0",
61
61
  "expo-keycloak-auth": "1.0.14",
62
62
  "jest": "^29.7.0",
63
63
  "jest-sonar-reporter": "^2.0.0",
64
- "multiplatform.one": "^1.0.0",
65
- "next": "^13.5.6",
66
- "prettier": "^3.1.1",
64
+ "multiplatform.one": "^1.0.2",
65
+ "next": "^14.0.4",
66
+ "prettier": "^3.2.4",
67
67
  "react": "^18.2.0",
68
68
  "react-native": "~0.73.2",
69
69
  "ts-node": "^10.9.2",
@@ -95,6 +95,7 @@
95
95
  "indent": 4
96
96
  },
97
97
  "dependencies": {
98
+ "@apollo/client": "^3.8.9",
98
99
  "expo-auth-session": "^5.4.0",
99
100
  "keycloak-js": "^23.0.4",
100
101
  "next-auth": "^4.24.5"
@@ -19,14 +19,12 @@
19
19
  * limitations under the License.
20
20
  */
21
21
 
22
- import React, { useEffect } from 'react';
23
- import type { ComponentType, ReactNode } from 'react';
22
+ import React, { ComponentType, PropsWithChildren, useEffect } from 'react';
24
23
  import { MultiPlatform } from 'multiplatform.one';
25
24
  import { useAuthConfig, useTokensFromQuery, useTokensFromState } from './hooks';
26
25
  import { useKeycloak } from './keycloak';
27
26
 
28
- export interface AuthenticatedProps {
29
- children: ReactNode;
27
+ export interface AuthenticatedProps extends PropsWithChildren {
30
28
  disabled?: boolean;
31
29
  loadingComponent?: ComponentType;
32
30
  loggedOutComponent?: ComponentType;
package/src/apollo.ts ADDED
@@ -0,0 +1,95 @@
1
+ /*
2
+ * File: /src/apollo.ts
3
+ * Project: @multiplatform.one/keycloak
4
+ * File Created: 13-01-2024 13:37:13
5
+ * Author: Clay Risser
6
+ * -----
7
+ * BitSpur (c) Copyright 2021 - 2024
8
+ *
9
+ * Licensed under the Apache License, Version 2.0 (the "License");
10
+ * you may not use this file except in compliance with the License.
11
+ * You may obtain a copy of the License at
12
+ *
13
+ * http://www.apache.org/licenses/LICENSE-2.0
14
+ *
15
+ * Unless required by applicable law or agreed to in writing, software
16
+ * distributed under the License is distributed on an "AS IS" BASIS,
17
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18
+ * See the License for the specific language governing permissions and
19
+ * limitations under the License.
20
+ */
21
+
22
+ import { useKeycloak } from './keycloak';
23
+ import { useQuery, useMutation, useSubscription } from '@apollo/client';
24
+ import type {
25
+ ApolloCache,
26
+ DefaultContext,
27
+ DocumentNode,
28
+ MutationHookOptions,
29
+ MutationTuple,
30
+ NoInfer,
31
+ OperationVariables,
32
+ QueryHookOptions,
33
+ QueryResult,
34
+ SubscriptionHookOptions,
35
+ SubscriptionResult,
36
+ TypedDocumentNode,
37
+ } from '@apollo/client';
38
+
39
+ export function useAuthQuery<TData = any, TVariables extends OperationVariables = OperationVariables>(
40
+ query: DocumentNode | TypedDocumentNode<TData, TVariables>,
41
+ options?: QueryHookOptions<NoInfer<TData>, NoInfer<TVariables>>,
42
+ ): QueryResult<TData, TVariables> {
43
+ const keycloak = useKeycloak();
44
+ return useQuery(query, {
45
+ ...options,
46
+ skip: options?.skip || !keycloak?.authenticated || !keycloak.token,
47
+ context: {
48
+ ...options?.context,
49
+ headers: {
50
+ ...(options?.context?.headers || {}),
51
+ authorization: `Bearer ${keycloak?.token}`,
52
+ },
53
+ },
54
+ });
55
+ }
56
+
57
+ export function useAuthMutation<
58
+ TData = any,
59
+ TVariables = OperationVariables,
60
+ TContext = DefaultContext,
61
+ TCache extends ApolloCache<any> = ApolloCache<any>,
62
+ >(
63
+ mutation: DocumentNode | TypedDocumentNode<TData, TVariables>,
64
+ options?: MutationHookOptions<NoInfer<TData>, NoInfer<TVariables>, TContext, TCache>,
65
+ ): MutationTuple<TData, TVariables, TContext, TCache> {
66
+ const keycloak = useKeycloak();
67
+ return useMutation(mutation, {
68
+ ...options,
69
+ context: {
70
+ ...options?.context,
71
+ headers: {
72
+ ...((options?.context as DefaultContext)?.headers || {}),
73
+ authorization: `Bearer ${keycloak?.token}`,
74
+ },
75
+ } as TContext,
76
+ });
77
+ }
78
+
79
+ export function useAuthSubscription<TData = any, TVariables extends OperationVariables = OperationVariables>(
80
+ subscription: DocumentNode | TypedDocumentNode<TData, TVariables>,
81
+ options?: SubscriptionHookOptions<NoInfer<TData>, NoInfer<TVariables>>,
82
+ ): SubscriptionResult<TData, TVariables> {
83
+ const keycloak = useKeycloak();
84
+ return useSubscription(subscription, {
85
+ ...options,
86
+ skip: options?.skip || !keycloak?.authenticated || !keycloak.token,
87
+ context: {
88
+ ...options?.context,
89
+ headers: {
90
+ ...((options?.context as DefaultContext)?.headers || {}),
91
+ authorization: `Bearer ${keycloak?.token}`,
92
+ },
93
+ },
94
+ });
95
+ }
package/src/index.ts CHANGED
@@ -20,6 +20,7 @@
20
20
  */
21
21
 
22
22
  export * from './Authenticated';
23
+ export * from './apollo';
23
24
  export * from './authConfig';
24
25
  export * from './hooks';
25
26
  export * from './keycloak';
@@ -21,6 +21,8 @@
21
21
 
22
22
  import type KeycloakClient from 'keycloak-js';
23
23
  import type { AccessTokenParsed, TokenParsed } from '../token';
24
+ import type { AuthOptions } from 'next-auth';
25
+ import type { GetSessionParams } from 'next-auth/react';
24
26
  import type { KeycloakLoginOptions, KeycloakLogoutOptions } from 'keycloak-js';
25
27
  import type { KeycloakMock } from '../types';
26
28
  import type { Session } from '../session/session';
@@ -155,7 +157,6 @@ export function useKeycloak() {
155
157
  const keycloak = useContext(KeycloakContext);
156
158
  if (keycloak) return keycloak;
157
159
  const { session, status } = useSession();
158
- if (MultiPlatform.isServer) return;
159
160
  if (MultiPlatform.isStorybook) {
160
161
  return new Keycloak({
161
162
  email: 'storybook@example.com',
@@ -168,8 +169,8 @@ export function useKeycloak() {
168
169
  }
169
170
  }
170
171
 
171
- export async function getKeycloak() {
172
- const session = await getSession();
172
+ export async function getKeycloak(options?: AuthOptions | GetSessionParams, req?: any, res?: any) {
173
+ const session = await getSession(options, req, res);
173
174
  if (session?.accessToken) return new Keycloak(session as Session);
174
175
  return new Keycloak();
175
176
  }
@@ -56,7 +56,7 @@ export function AfterAuth({ children }: AfterAuthProps) {
56
56
  }, [keycloak?.refreshToken]);
57
57
 
58
58
  useEffect(() => {
59
- if (keycloak?.authenticated) logger.debug('authenticated', keycloak.authenticated);
59
+ if (authConfig.debug && keycloak?.authenticated) logger.debug('authenticated', keycloak.authenticated);
60
60
  }, [keycloak?.authenticated]);
61
61
 
62
62
  return <>{children}</>;
package/src/routes.ts CHANGED
@@ -27,25 +27,24 @@ import type { Session } from './session';
27
27
  import { getServerSession } from 'next-auth';
28
28
  import { jwtDecode } from 'jwt-decode';
29
29
 
30
- const KeycloakProvider = require('next-auth/providers/keycloak').default;
31
- const NextAuth = require('next-auth').default;
32
- const NextResponse = require('next/server').NextResponse;
30
+ const KeycloakProvider = require('next-auth/providers/keycloak')
31
+ .default as typeof import('next-auth/providers/keycloak').default;
33
32
 
34
- const logger = console;
35
33
  let _nextAuth: AuthOptions | undefined;
36
34
 
37
- export function createAuthHandler(options: CreateAuthHandlerOptions = {}) {
38
- const handler = NextAuth(createAuthOptions(options));
39
- return {
40
- GET: handler,
41
- POST: handler,
42
- };
35
+ const NextAuth = require('next-auth').default as typeof import('next-auth').default;
36
+ const NextResponse = require('next/server').NextResponse as typeof import('next/server').NextResponse;
37
+
38
+ const logger = console;
39
+
40
+ export function createAuthHandler(options = createNextAuthOptions()) {
41
+ return NextAuth(options);
43
42
  }
44
43
 
45
- export function createLogoutHandler(options: CreateAuthHandlerOptions = {}) {
44
+ export function createLogoutHandler(options = createNextAuthOptions()) {
46
45
  return {
47
46
  async GET() {
48
- const idToken = ((await getServerSession(createAuthOptions(options))) as Session)?.idToken;
47
+ const idToken = ((await getServerSession(options)) as Session)?.idToken;
49
48
  if (idToken) {
50
49
  try {
51
50
  await fetch(
@@ -66,7 +65,7 @@ export function createLogoutHandler(options: CreateAuthHandlerOptions = {}) {
66
65
  };
67
66
  }
68
67
 
69
- function createAuthOptions(options: CreateAuthHandlerOptions = {}) {
68
+ export function createNextAuthOptions(options: CreateAuthHandlerOptions = {}) {
70
69
  if (_nextAuth) return _nextAuth;
71
70
  _nextAuth = {
72
71
  ...options.nextAuth,
@@ -122,31 +121,6 @@ function createAuthOptions(options: CreateAuthHandlerOptions = {}) {
122
121
  return _nextAuth;
123
122
  }
124
123
 
125
- async function refreshAccessToken(nextToken: NextToken) {
126
- const res = await fetch(process.env.REFRESH_TOKEN_URL || '', {
127
- method: 'POST',
128
- headers: {
129
- 'Content-Type': 'application/x-www-form-urlencoded',
130
- },
131
- body: new URLSearchParams({
132
- client_id: process.env.KEYCLOAK_CLIENT_ID || '',
133
- client_secret: process.env.KEYCLOAK_CLIENT_SECRET || '',
134
- grant_type: 'refresh_token',
135
- refresh_token: nextToken.refreshToken,
136
- }),
137
- });
138
- const refreshToken = await res.json();
139
- if (!res.ok) throw refreshToken;
140
- return {
141
- ...nextToken,
142
- accessToken: refreshToken.access_token,
143
- decoded: jwtDecode(refreshToken.access_token),
144
- expiresAt: Math.floor(Date.now() / 1000) + Number(refreshToken.expires_in),
145
- idToken: refreshToken.id_token,
146
- refreshToken: refreshToken.refresh_token,
147
- };
148
- }
149
-
150
124
  export interface CreateAuthHandlerOptions {
151
125
  keycloakProvider?: Partial<OAuthUserConfig<any>>;
152
126
  nextAuth?: AuthOptions;
@@ -161,3 +135,31 @@ export interface NextToken extends JWT {
161
135
  refreshToken: string;
162
136
  roles: string[];
163
137
  }
138
+
139
+ async function refreshAccessToken(nextToken: NextToken) {
140
+ const res = await fetch(
141
+ `${process.env.KEYCLOAK_BASE_URL}/realms/${process.env.KEYCLOAK_REALM || 'master'}/protocol/openid-connect/token`,
142
+ {
143
+ method: 'POST',
144
+ headers: {
145
+ 'Content-Type': 'application/x-www-form-urlencoded',
146
+ },
147
+ body: new URLSearchParams({
148
+ client_id: process.env.KEYCLOAK_CLIENT_ID || '',
149
+ client_secret: process.env.KEYCLOAK_CLIENT_SECRET || '',
150
+ grant_type: 'refresh_token',
151
+ refresh_token: nextToken.refreshToken,
152
+ }),
153
+ },
154
+ );
155
+ const refreshToken = await res.json();
156
+ if (!res.ok) throw refreshToken;
157
+ return {
158
+ ...nextToken,
159
+ accessToken: refreshToken.access_token,
160
+ decoded: jwtDecode(refreshToken.access_token),
161
+ expiresAt: Math.floor(Date.now() / 1000) + Number(refreshToken.expires_in),
162
+ idToken: refreshToken.id_token,
163
+ refreshToken: refreshToken.refresh_token,
164
+ };
165
+ }
@@ -1,5 +1,5 @@
1
1
  /*
2
- * File: /src/session.ts
2
+ * File: /src/session/session.ts
3
3
  * Project: @multiplatform.one/keycloak
4
4
  * File Created: 10-01-2024 02:31:26
5
5
  * Author: Clay Risser
@@ -19,21 +19,31 @@
19
19
  * limitations under the License.
20
20
  */
21
21
 
22
- import type { Session as NextSession } from 'next-auth';
23
- import type { SessionContextValue as NextSessionContextValue, UseSessionOptions } from 'next-auth/react';
22
+ import type { AuthOptions, Session as NextSession } from 'next-auth';
24
23
  import { MultiPlatform } from 'multiplatform.one';
25
24
  import { useSession as useNextSession, getSession as getNextSession } from 'next-auth/react';
25
+ import type {
26
+ GetSessionParams,
27
+ SessionContextValue as NextSessionContextValue,
28
+ UseSessionOptions,
29
+ } from 'next-auth/react';
26
30
 
27
- let _getServerSession: (() => Promise<Session | null>) | undefined;
31
+ let _getServerSession: ((options?: AuthOptions, req?: any, res?: any) => Promise<Session | null>) | undefined;
28
32
 
29
- export async function getSession(): Promise<Session | null> {
33
+ export async function getSession(
34
+ options?: AuthOptions | GetSessionParams,
35
+ req?: any,
36
+ res?: any,
37
+ ): Promise<Session | null> {
30
38
  if (MultiPlatform.isServer) {
31
- if (typeof _getServerSession === 'function') return _getServerSession();
39
+ if (typeof _getServerSession === 'function') return _getServerSession(options as AuthOptions, req, res);
32
40
  const getSession = (await import('next-auth')).getServerSession;
33
- _getServerSession = () => getSession();
34
- return _getServerSession();
41
+ _getServerSession = (options?: AuthOptions, req?: any, res?: any) => {
42
+ return req && res ? getSession(req, res, options as any) : getSession(options as any);
43
+ };
44
+ return _getServerSession(options as AuthOptions, req, res);
35
45
  }
36
- return getNextSession();
46
+ return getNextSession(options as GetSessionParams);
37
47
  }
38
48
 
39
49
  export type SessionContextValue<R extends boolean> = Partial<