Skip to content

Commit 316458c

Browse files
ryanbas21cerebrl
authored andcommitted
feat: implement-authorize-oidc-client
introduce the oidc-client with the authorize api. authoirize handles the calling of authorize routes based on the well-known config. when a p1 env is detected, it will use a post request otherwise, a background request is done via a hidden iframe
1 parent 26c6983 commit 316458c

5 files changed

Lines changed: 178 additions & 14 deletions

File tree

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query';
2+
3+
const authorizeSlice = createApi({
4+
reducerPath: 'authorizeSlice',
5+
baseQuery: fetchBaseQuery({
6+
credentials: 'include',
7+
prepareHeaders: (headers) => {
8+
headers.set('Content-Type', 'application/json');
9+
headers.set('Accept', 'application/json');
10+
headers.set('x-requested-with', 'ping-sdk');
11+
headers.set('x-requested-platform', 'javascript');
12+
13+
return headers;
14+
},
15+
}),
16+
endpoints: (builder) => ({
17+
handleAuthorize: builder.query<string, string>({
18+
query: (authorizeUrl) => authorizeUrl,
19+
}),
20+
}),
21+
});
22+
23+
export { authorizeSlice };
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
import { recreateAuthorizeUrl, handleAuthorize } from './client.store.utils.js';
2+
import { describe, expect, it, vi, beforeEach, afterEach } from 'vitest';
3+
4+
// Mock createAuthorizeUrl from sdk to avoid actual URL generation logic or network calls
5+
vi.mock('@forgerock/sdk-oidc', () => {
6+
return {
7+
createAuthorizeUrl: vi
8+
.fn()
9+
.mockResolvedValue(
10+
'https://example.com/authorize?client_id=client_id&redirect_uri=https%3A%2F%2Fexample.com%2Fredirect&scope=openid&state=state&response_type=code',
11+
),
12+
};
13+
});
14+
15+
// Stub the global fetch used inside handleAuthorize so it returns predictable JSON
16+
beforeEach(() => {
17+
vi.stubGlobal(
18+
'fetch',
19+
vi.fn().mockResolvedValue({
20+
json: async () => ({
21+
authorizeResponse: {
22+
code: 'code',
23+
state: 'state',
24+
},
25+
}),
26+
}),
27+
);
28+
});
29+
30+
afterEach(() => {
31+
vi.unstubAllGlobals();
32+
});
33+
34+
describe('client-store utilities', () => {
35+
it('should handle authorize', async () => {
36+
const result = await handleAuthorize('https://example.com/authorize');
37+
expect(result).toEqual({
38+
code: 'code',
39+
state: 'state',
40+
});
41+
});
42+
43+
it('should recreate authorize url', async () => {
44+
const result = await recreateAuthorizeUrl(
45+
{
46+
error: 'error',
47+
error_description: 'error_description',
48+
state: 'state',
49+
},
50+
'https://example.com/authorize',
51+
{
52+
clientId: 'client_id',
53+
redirectUri: 'https://example.com/redirect',
54+
scope: 'openid',
55+
state: 'state',
56+
responseType: 'code',
57+
},
58+
);
59+
expect(result).toEqual({
60+
error: 'error',
61+
error_description: 'error_description',
62+
state: 'state',
63+
redirectUrl:
64+
'https://example.com/authorize?client_id=client_id&redirect_uri=https%3A%2F%2Fexample.com%2Fredirect&scope=openid&state=state&response_type=code',
65+
});
66+
});
67+
});
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import type { ActionTypes, RequestMiddleware } from '@forgerock/sdk-request-middleware';
2+
import type { logger as loggerFn } from '@forgerock/sdk-logger';
3+
4+
import { configureStore } from '@reduxjs/toolkit';
5+
import { fetchWellKnownConfig } from './wellknown.api.js';
6+
import { authorizeSlice } from './authorize.slice.js';
7+
8+
export function createOidcStore<ActionType extends ActionTypes>({
9+
requestMiddleware,
10+
logger,
11+
}: {
12+
requestMiddleware?: RequestMiddleware<ActionType, unknown>[];
13+
logger?: ReturnType<typeof loggerFn>;
14+
}) {
15+
return configureStore({
16+
reducer: {
17+
[fetchWellKnownConfig.reducerPath]: fetchWellKnownConfig.reducer,
18+
[authorizeSlice.reducerPath]: authorizeSlice.reducer,
19+
},
20+
middleware: (getDefaultMiddleware) =>
21+
getDefaultMiddleware({
22+
thunk: {
23+
extraArgument: {
24+
/**
25+
* This becomes the `api.extra` argument, and will be passed into the
26+
* customer query wrapper for `baseQuery`
27+
*/
28+
requestMiddleware,
29+
logger,
30+
},
31+
},
32+
})
33+
.concat(fetchWellKnownConfig.middleware)
34+
.concat(authorizeSlice.middleware),
35+
});
36+
}

packages/oidc-client/tsconfig.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,18 @@
1818
{
1919
"path": "../sdk-effects/iframe-manager"
2020
},
21+
{
22+
"path": "../sdk-effects/sdk-request-middleware"
23+
},
24+
{
25+
"path": "../sdk-effects/oidc"
26+
},
27+
{
28+
"path": "../sdk-effects/logger"
29+
},
30+
{
31+
"path": "../sdk-effects/iframe-manager"
32+
},
2133
{
2234
"path": "./tsconfig.lib.json"
2335
},

pnpm-lock.yaml

Lines changed: 40 additions & 14 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)