Skip to content

Commit b81aec3

Browse files
committed
chore: refactor
1 parent 9a03632 commit b81aec3

File tree

8 files changed

+75
-81
lines changed

8 files changed

+75
-81
lines changed

e2e/davinci-app/components/social-login-button.ts

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,11 @@ export default function submitButtonComponent(
1717
button.value = collector.output.label;
1818
button.innerHTML = collector.output.label;
1919
button.onclick = () => {
20-
const url = updater();
21-
if (typeof url === 'string') {
22-
window.location.assign(url);
20+
updater();
21+
if ('url' in collector.output && typeof collector.output.url === 'string') {
22+
window.location.assign(collector.output.url);
2323
} else {
24-
/**
25-
* this is an error now
26-
**/
27-
console.error(url);
24+
console.error('no url to continue from');
2825
}
2926
};
3027

packages/davinci-client/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
"@forgerock/sdk-oidc": "workspace:*",
2828
"@forgerock/sdk-request-middleware": "workspace:*",
2929
"@forgerock/sdk-types": "workspace:*",
30+
"@forgerock/storage": "workspace:*",
3031
"@reduxjs/toolkit": "catalog:",
3132
"immer": "catalog:"
3233
},

packages/davinci-client/src/lib/client.store.ts

Lines changed: 48 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
* Import RTK slices and api
99
*/
1010
import { CustomLogger, logger as loggerFn, LogLevel } from '@forgerock/sdk-logger';
11+
import { createStorage } from '@forgerock/storage';
1112

1213
import { createClientStore, handleUpdateValidateError, RootState } from './client.store.utils.js';
1314
import { nodeSlice } from './node.slice.js';
@@ -28,7 +29,6 @@ import type {
2829
} from './davinci.types.js';
2930
import type {
3031
SingleValueCollectors,
31-
IdpCollector,
3232
MultiSelectCollector,
3333
ObjectValueCollectors,
3434
PhoneNumberInputValue,
@@ -41,8 +41,7 @@ import type {
4141
Validator,
4242
} from './client.types.js';
4343
import { returnValidator } from './collector.utils.js';
44-
import { StartNode } from './node.types.js';
45-
import { returnRedirectUrlForSocialLogin } from './davinci.utils.js';
44+
import { ContinueNode, StartNode } from './node.types.js';
4645

4746
/**
4847
* Create a client function that returns a set of methods
@@ -66,7 +65,10 @@ export async function davinci<ActionType extends ActionTypes = ActionTypes>({
6665
}) {
6766
const log = loggerFn({ level: logger?.level || 'error', custom: logger?.custom });
6867
const store = createClientStore({ requestMiddleware, logger: log });
69-
68+
const serverStorage = createStorage<ContinueNode['server']>(
69+
{ storeType: 'localStorage' },
70+
'socialLoginUrl',
71+
);
7072
if (!config.serverConfig.wellknown) {
7173
const error = new Error(
7274
'`wellknown` property is a required as part of the `config.serverConfig`',
@@ -114,17 +116,23 @@ export async function davinci<ActionType extends ActionTypes = ActionTypes>({
114116
* @param collector IdpCollector
115117
* @returns {function}
116118
*/
117-
externalIdp: (collector: IdpCollector): (() => string | InternalErrorResponse) => {
119+
externalIdp: (): (() => Promise<void | InternalErrorResponse>) => {
118120
const rootState: RootState = store.getState();
119-
120121
const serverSlice = nodeSlice.selectors.selectServer(rootState);
121122

122-
return () => {
123-
const result = returnRedirectUrlForSocialLogin(serverSlice, collector, log);
124-
if (typeof result == 'string') {
125-
return result;
126-
}
127-
return result;
123+
if (serverSlice && serverSlice.status === 'continue') {
124+
return async () => {
125+
await serverStorage.set(serverSlice);
126+
};
127+
}
128+
return async () => {
129+
return {
130+
error: {
131+
message:
132+
'Not in a continue node state, must be in a continue node to use external idp method',
133+
type: 'state_error',
134+
},
135+
} as InternalErrorResponse;
128136
};
129137
},
130138

@@ -178,12 +186,34 @@ export async function davinci<ActionType extends ActionTypes = ActionTypes>({
178186
* @method: resume - Resume a social login flow when returned to application
179187
* @returns unknown
180188
*/
181-
resume: async ({ continueToken }: { continueToken: string }) => {
182-
await store.dispatch(davinciApi.endpoints.resume.initiate({ continueToken }));
183-
184-
const node = nodeSlice.selectSlice(store.getState());
185-
186-
return node;
189+
resume: async ({
190+
continueToken,
191+
}: {
192+
continueToken: string;
193+
}): Promise<InternalErrorResponse | NodeStates> => {
194+
try {
195+
const serverInfo = await serverStorage.get();
196+
if (serverInfo && '_links' in serverInfo) {
197+
await store.dispatch(davinciApi.endpoints.resume.initiate({ continueToken, serverInfo }));
198+
await serverStorage.remove();
199+
200+
const node = nodeSlice.selectSlice(store.getState());
201+
202+
return node;
203+
} else {
204+
throw new Error('failure to get continue url');
205+
}
206+
} catch {
207+
// logger.error('No url found in collector, social login needs a url in the collector');
208+
return {
209+
error: {
210+
message:
211+
'No url found in storage, social login needs a continue url which is saved in local storage. You may have cleared your browser data',
212+
type: 'internal_error',
213+
},
214+
type: 'internal_error',
215+
};
216+
}
187217
},
188218

189219
/**

packages/davinci-client/src/lib/davinci.api.ts

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -347,10 +347,10 @@ export const davinciApi = createApi({
347347
handleResponse(cacheEntry, api.dispatch, response?.status || 0, logger);
348348
},
349349
}),
350-
resume: builder.query<unknown, { continueToken: string }>({
351-
async queryFn({ continueToken }, api, _c, baseQuery) {
352-
const continueUrl = window.localStorage.getItem('continueUrl') || null;
350+
resume: builder.query<unknown, { serverInfo: ContinueNode['server']; continueToken: string }>({
351+
async queryFn({ serverInfo, continueToken }, api, _c, baseQuery) {
353352
const { requestMiddleware, logger } = api.extra as Extras;
353+
const links = serverInfo._links;
354354

355355
if (!continueToken) {
356356
return {
@@ -362,7 +362,12 @@ export const davinciApi = createApi({
362362
},
363363
};
364364
}
365-
if (!continueUrl) {
365+
if (
366+
!links ||
367+
!('continue' in links) ||
368+
!('href' in links['continue']) ||
369+
!links['continue'].href
370+
) {
366371
return {
367372
error: {
368373
data: 'No continue url',
@@ -373,10 +378,7 @@ export const davinciApi = createApi({
373378
};
374379
}
375380

376-
if (continueUrl) {
377-
window.localStorage.removeItem('continueUrl');
378-
}
379-
381+
const continueUrl = links['continue'].href;
380382
const request: FetchArgs = {
381383
url: continueUrl,
382384
credentials: 'include',

packages/davinci-client/src/lib/davinci.utils.ts

Lines changed: 1 addition & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@ import type { Dispatch } from '@reduxjs/toolkit';
1111

1212
import { logger as loggerFn } from '@forgerock/sdk-logger';
1313

14-
import type { RootState } from './client.store.utils.js';
15-
1614
import { nodeSlice } from './node.slice.js';
1715

1816
import type {
@@ -24,9 +22,7 @@ import type {
2422
DaVinciSuccessResponse,
2523
} from './davinci.types.js';
2624
import type { ContinueNode } from './node.types.js';
27-
import { DeviceValue, IdpCollector, PhoneNumberInputValue } from './collector.types.js';
28-
import { InternalErrorResponse } from './client.types.js';
29-
25+
import { DeviceValue, PhoneNumberInputValue } from './collector.types.js';
3026
/**
3127
* @function transformSubmitRequest - Transforms a NextNode into a DaVinciRequest for form submissions
3228
* @param {ContinueNode} node - The node to transform into a DaVinciRequest
@@ -245,44 +241,3 @@ export function handleResponse(
245241
}
246242
}
247243
}
248-
249-
export function returnRedirectUrlForSocialLogin(
250-
serverSlice: RootState['node']['server'],
251-
collector: IdpCollector,
252-
logger: ReturnType<typeof loggerFn>,
253-
): InternalErrorResponse | string {
254-
if (serverSlice && '_links' in serverSlice) {
255-
const continueUrl = serverSlice._links?.['continue']?.href ?? null;
256-
if (continueUrl) {
257-
window.localStorage.setItem('continueUrl', continueUrl);
258-
if (collector.output.url) {
259-
return collector.output.url;
260-
} else {
261-
logger.error('No url found in collector, social login needs a url in the collector');
262-
return {
263-
error: {
264-
message:
265-
'No url found in collector, social login needs a url in the collector to navigate to',
266-
type: 'network_error',
267-
},
268-
type: 'internal_error',
269-
};
270-
}
271-
}
272-
}
273-
/**
274-
* If we have no continue url
275-
* we have to return an error
276-
**/
277-
logger.error(
278-
'No Continue Url found, social login needs a continue url to be saved in localStorage',
279-
);
280-
return {
281-
error: {
282-
message:
283-
'No Continue Url found, social login needs a continue url to be saved in localStorage',
284-
type: 'network_error',
285-
},
286-
type: 'internal_error',
287-
};
288-
}

packages/davinci-client/tsconfig.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
},
1212
"references": [
1313
{
14-
"path": "../sdk-effects/logger"
14+
"path": "../sdk-effects/storage"
1515
},
1616
{
1717
"path": "../sdk-types"
@@ -22,6 +22,9 @@
2222
{
2323
"path": "../sdk-effects/oidc"
2424
},
25+
{
26+
"path": "../sdk-effects/logger"
27+
},
2528
{
2629
"path": "./tsconfig.lib.json"
2730
},

packages/davinci-client/tsconfig.lib.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
],
3333
"references": [
3434
{
35-
"path": "../sdk-effects/logger/tsconfig.lib.json"
35+
"path": "../sdk-effects/storage/tsconfig.lib.json"
3636
},
3737
{
3838
"path": "../sdk-types/tsconfig.lib.json"
@@ -42,6 +42,9 @@
4242
},
4343
{
4444
"path": "../sdk-effects/oidc/tsconfig.lib.json"
45+
},
46+
{
47+
"path": "../sdk-effects/logger/tsconfig.lib.json"
4548
}
4649
]
4750
}

pnpm-lock.yaml

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

0 commit comments

Comments
 (0)