@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.
- package/lib/Authenticated.d.mts +2 -3
- package/lib/Authenticated.d.ts +2 -3
- package/lib/Authenticated.js +4 -4
- package/lib/Authenticated.mjs +3 -3
- package/lib/apollo.d.mts +7 -0
- package/lib/apollo.d.ts +7 -0
- package/lib/apollo.js +15 -0
- package/lib/apollo.mjs +15 -0
- package/lib/chunk-267L3NLO.mjs +53 -0
- package/lib/{chunk-NH335CDK.js → chunk-2VGMJ7WP.js} +7 -5
- package/lib/{chunk-Y23BWOII.mjs → chunk-3KAZ37SK.mjs} +2 -2
- package/lib/{chunk-Y5MS3XVZ.mjs → chunk-5CWGWY74.mjs} +1 -1
- package/lib/{chunk-OA5TSQWZ.mjs → chunk-6Q4DC5JX.mjs} +1 -1
- package/lib/{chunk-UH4K7HGE.mjs → chunk-7NZPJ2EN.mjs} +6 -8
- package/lib/{chunk-2BSUCVXL.js → chunk-K2FTCH55.js} +2 -2
- package/lib/{chunk-FU4CT24B.mjs → chunk-KWNIT4G4.mjs} +7 -5
- package/lib/{chunk-2BKS6UM5.js → chunk-NCIQ66UP.js} +3 -3
- package/lib/{chunk-ZW4GP2I5.js → chunk-NWZCPYQP.js} +5 -7
- package/lib/{chunk-X53FOCXA.js → chunk-S5HUGQLF.js} +2 -2
- package/lib/{chunk-OZLV3US5.js → chunk-VFQKAKK4.js} +7 -7
- package/lib/chunk-VPYXLUMD.js +53 -0
- package/lib/{chunk-CGLMLNUS.mjs → chunk-W4PGLIAZ.mjs} +2 -2
- package/lib/index.d.mts +3 -1
- package/lib/index.d.ts +3 -1
- package/lib/index.js +18 -10
- package/lib/index.mjs +16 -8
- package/lib/keycloak/context.d.mts +2 -2
- package/lib/keycloak/context.d.ts +2 -2
- package/lib/keycloak/index.d.mts +2 -2
- package/lib/keycloak/index.d.ts +2 -2
- package/lib/keycloak/index.js +3 -3
- package/lib/keycloak/index.mjs +2 -2
- package/lib/keycloak/keycloak.d.mts +3 -3
- package/lib/keycloak/keycloak.d.ts +3 -3
- package/lib/keycloak/keycloak.js +3 -3
- package/lib/keycloak/keycloak.mjs +2 -2
- package/lib/keycloak/keycloak.native.js +2 -2
- package/lib/keycloak/keycloak.native.mjs +1 -1
- package/lib/provider/AfterAuth.js +4 -4
- package/lib/provider/AfterAuth.mjs +3 -3
- package/lib/provider/AuthProvider/AuthProvider.js +5 -5
- package/lib/provider/AuthProvider/AuthProvider.mjs +4 -4
- package/lib/provider/AuthProvider/AuthProvider.native.js +4 -4
- package/lib/provider/AuthProvider/AuthProvider.native.mjs +3 -3
- package/lib/provider/AuthProvider/index.js +5 -5
- package/lib/provider/AuthProvider/index.mjs +4 -4
- package/lib/provider/KeycloakProvider.js +6 -6
- package/lib/provider/KeycloakProvider.mjs +5 -5
- package/lib/provider/index.js +6 -6
- package/lib/provider/index.mjs +5 -5
- package/lib/routes.d.mts +6 -7
- package/lib/routes.d.ts +6 -7
- package/lib/routes.js +23 -23
- package/lib/routes.mjs +23 -23
- package/lib/session/index.js +2 -2
- package/lib/session/index.mjs +1 -1
- package/lib/session/session.d.mts +3 -3
- package/lib/session/session.d.ts +3 -3
- package/lib/session/session.js +2 -2
- package/lib/session/session.mjs +1 -1
- package/package.json +7 -6
- package/src/Authenticated.tsx +2 -4
- package/src/apollo.ts +95 -0
- package/src/index.ts +1 -0
- package/src/keycloak/keycloak.ts +4 -3
- package/src/provider/AfterAuth.tsx +1 -1
- package/src/routes.ts +40 -38
- 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
|
-
|
|
13
|
-
|
|
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,
|
|
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
|
|
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(
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
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
|
-
|
|
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
|
-
|
|
13
|
-
|
|
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(
|
|
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
|
|
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(
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
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
|
};
|
package/lib/session/index.js
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
|
|
5
|
-
var
|
|
5
|
+
var _chunk2VGMJ7WPjs = require('../chunk-2VGMJ7WP.js');
|
|
6
6
|
require('../chunk-P57PW2II.js');
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
|
|
10
|
-
exports.getSession =
|
|
10
|
+
exports.getSession = _chunk2VGMJ7WPjs.getSession; exports.useSession = _chunk2VGMJ7WPjs.useSession;
|
package/lib/session/index.mjs
CHANGED
|
@@ -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'>>;
|
package/lib/session/session.d.ts
CHANGED
|
@@ -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'>>;
|
package/lib/session/session.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"use strict";Object.defineProperty(exports, "__esModule", {value: true});
|
|
2
2
|
|
|
3
3
|
|
|
4
|
-
var
|
|
4
|
+
var _chunk2VGMJ7WPjs = require('../chunk-2VGMJ7WP.js');
|
|
5
5
|
require('../chunk-P57PW2II.js');
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
|
|
9
|
-
exports.getSession =
|
|
9
|
+
exports.getSession = _chunk2VGMJ7WPjs.getSession; exports.useSession = _chunk2VGMJ7WPjs.useSession;
|
package/lib/session/session.mjs
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@multiplatform.one/keycloak",
|
|
3
|
-
"version": "0.
|
|
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.
|
|
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.
|
|
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.
|
|
65
|
-
"next": "^
|
|
66
|
-
"prettier": "^3.
|
|
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"
|
package/src/Authenticated.tsx
CHANGED
|
@@ -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
package/src/keycloak/keycloak.ts
CHANGED
|
@@ -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')
|
|
31
|
-
|
|
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
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
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
|
|
44
|
+
export function createLogoutHandler(options = createNextAuthOptions()) {
|
|
46
45
|
return {
|
|
47
46
|
async GET() {
|
|
48
|
-
const idToken = ((await getServerSession(
|
|
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
|
|
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
|
+
}
|
package/src/session/session.ts
CHANGED
|
@@ -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(
|
|
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 = () =>
|
|
34
|
-
|
|
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<
|