From 65004583340d38b105c12964108b0c5aaa2de3c8 Mon Sep 17 00:00:00 2001 From: aeneasr <3372410+aeneasr@users.noreply.github.com> Date: Fri, 10 Jan 2025 11:04:47 +0100 Subject: [PATCH] chore: synchronize workspaces --- .../typescript-fetch/src/contrib/utils.ts | 14 +- contrib/fetch/src/utils.ts | 127 +++++++++--------- 2 files changed, 78 insertions(+), 63 deletions(-) diff --git a/clients/client/typescript-fetch/src/contrib/utils.ts b/clients/client/typescript-fetch/src/contrib/utils.ts index ba77f9ff325..7e2c9def750 100644 --- a/clients/client/typescript-fetch/src/contrib/utils.ts +++ b/clients/client/typescript-fetch/src/contrib/utils.ts @@ -16,8 +16,10 @@ export type ValidationErrorHandler = (body: T) => void; type FlowErrorHandlerProps = { /** * When the SDK returns an error indicating that the flow needs to be restarted, this function is called. + * + * @param useFlowId - If provided, the SDK should use this flow ID to not lose context of the flow. */ - onRestartFlow: () => void; + onRestartFlow: (useFlowId?: string) => void; /** * When the SDK returns a validation error, this function is called. The result should be used to update the @@ -43,13 +45,19 @@ type FlowErrorHandlerProps = { */ export const handleFlowError = (opts: FlowErrorHandlerProps) => - async (err: unknown) => { + async (err: unknown): Promise => { if (isResponseError(err)) { switch (err.response.status) { case 404: // Does not exist opts.onRestartFlow(); return; case 410: // Expired + const body = await toBody(err.response); + console.log({body}) + if (isSelfServiceFlowExpiredError(body)) { + opts.onRestartFlow(body.use_flow_id); + return; + } // Re-initialize the flow opts.onRestartFlow(); return; @@ -68,7 +76,7 @@ export const handleFlowError = opts.onRedirect(body.redirect_browser_to, true); return; } else if (isSelfServiceFlowExpiredError(body)) { - opts.onRestartFlow(); + opts.onRestartFlow(body.use_flow_id); return; } else if (isNeedsPrivilegedSessionError(body)) { opts.onRedirect(body.redirect_browser_to, true); diff --git a/contrib/fetch/src/utils.ts b/contrib/fetch/src/utils.ts index ba77f9ff325..d85664e1bb2 100644 --- a/contrib/fetch/src/utils.ts +++ b/contrib/fetch/src/utils.ts @@ -16,8 +16,10 @@ export type ValidationErrorHandler = (body: T) => void; type FlowErrorHandlerProps = { /** * When the SDK returns an error indicating that the flow needs to be restarted, this function is called. + * + * @param useFlowId - If provided, the SDK should use this flow ID to not lose context of the flow. */ - onRestartFlow: () => void; + onRestartFlow: (useFlowId?: string) => void; /** * When the SDK returns a validation error, this function is called. The result should be used to update the @@ -42,74 +44,79 @@ type FlowErrorHandlerProps = { * @param opts - The configuration object. */ export const handleFlowError = - (opts: FlowErrorHandlerProps) => - async (err: unknown) => { - if (isResponseError(err)) { - switch (err.response.status) { - case 404: // Does not exist - opts.onRestartFlow(); - return; - case 410: // Expired - // Re-initialize the flow - opts.onRestartFlow(); - return; - case 400: - return opts.onValidationError( - // TODO: maybe we can do actual type checking here? - (await err.response.json()) as unknown as T - ); - case 403: // This typically happens with CSRF violations. - case 422: { - const body = await toBody(err.response); - if ( - isBrowserLocationChangeRequired(body) && - body.redirect_browser_to - ) { - opts.onRedirect(body.redirect_browser_to, true); - return; - } else if (isSelfServiceFlowExpiredError(body)) { - opts.onRestartFlow(); - return; - } else if (isNeedsPrivilegedSessionError(body)) { - opts.onRedirect(body.redirect_browser_to, true); - return; - } else if (isCsrfError(body)) { - opts.onRestartFlow(); - return; - } + (opts: FlowErrorHandlerProps) => + async (err: unknown): Promise => { + if (isResponseError(err)) { + switch (err.response.status) { + case 404: // Does not exist + opts.onRestartFlow(); + return; + case 410: // Expired + const body = await toBody(err.response); + if (isSelfServiceFlowExpiredError(body)) { + opts.onRestartFlow(body.use_flow_id); + return; + } + // Re-initialize the flow + opts.onRestartFlow(); + return; + case 400: + return opts.onValidationError( + // TODO: maybe we can do actual type checking here? + (await err.response.json()) as unknown as T + ); + case 403: // This typically happens with CSRF violations. + case 422: { + const body = await toBody(err.response); + if ( + isBrowserLocationChangeRequired(body) && + body.redirect_browser_to + ) { + opts.onRedirect(body.redirect_browser_to, true); + return; + } else if (isSelfServiceFlowExpiredError(body)) { + opts.onRestartFlow(body.use_flow_id); + return; + } else if (isNeedsPrivilegedSessionError(body)) { + opts.onRedirect(body.redirect_browser_to, true); + return; + } else if (isCsrfError(body)) { + opts.onRestartFlow(); + return; + } - throw new ResponseError( - err.response, - "The Ory API endpoint returned a response code the SDK does not know how to handle. Please check the network tab for more information:" + - JSON.stringify(body) - ); - } + throw new ResponseError( + err.response, + "The Ory API endpoint returned a response code the SDK does not know how to handle. Please check the network tab for more information:" + + JSON.stringify(body) + ); + } - default: - throw new ResponseError( - err.response, - "The Ory API endpoint returned a response code the SDK does not know how to handle. Please check the network tab for more information." - ); - } - } else if (err instanceof FetchError) { - throw new FetchError( - err, - "Unable to call the API endpoint. Ensure that CORS is set up correctly and that you have provided a valid SDK URL to Ory Elements." - ); - } else if (err instanceof RequiredError) { - // TODO (@aeneasr) Happens on submit usually. Not sure how to handle yet. - } + default: + throw new ResponseError( + err.response, + "The Ory API endpoint returned a response code the SDK does not know how to handle. Please check the network tab for more information." + ); + } + } else if (err instanceof FetchError) { + throw new FetchError( + err, + "Unable to call the API endpoint. Ensure that CORS is set up correctly and that you have provided a valid SDK URL to Ory Elements." + ); + } else if (err instanceof RequiredError) { + // TODO (@aeneasr) Happens on submit usually. Not sure how to handle yet. + } - throw err; - }; + throw err; + }; export async function toBody(response: Response): Promise { try { return (await response.clone().json()) as unknown; } catch (e) { throw new ResponseError( - response, - "The Ory API endpoint returned a response the SDK does not know how to handle:" + + response, + "The Ory API endpoint returned a response the SDK does not know how to handle:" + (await response.text()) ); }