Skip to content

Commit

Permalink
refactor: some cleanup and error handling
Browse files Browse the repository at this point in the history
  • Loading branch information
porcellus committed Sep 28, 2024
1 parent cfec14f commit e95511a
Show file tree
Hide file tree
Showing 9 changed files with 125 additions and 20 deletions.
9 changes: 8 additions & 1 deletion lib/build/recipe/oauth2provider/api/implementation.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ function getAPIImplementation() {
isDirectCall: true,
userContext,
});
if ("error" in response) {
return response;
}
const respAfterInternalRedirects = await utils_1.handleLoginInternalRedirects({
response,
cookie: options.req.getHeaderValue("cookie"),
Expand Down Expand Up @@ -69,10 +72,14 @@ function getAPIImplementation() {
});
},
loginInfoGET: async ({ loginChallenge, options, userContext }) => {
const { client } = await options.recipeImplementation.getLoginRequest({
const loginRes = await options.recipeImplementation.getLoginRequest({
challenge: loginChallenge,
userContext,
});
if (loginRes.status === "ERROR") {
return loginRes;
}
const { client } = loginRes;
return {
status: "OK",
info: {
Expand Down
17 changes: 13 additions & 4 deletions lib/build/recipe/oauth2provider/api/utils.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,19 @@ export declare function loginGET({
setCookie?: string;
userContext: UserContext;
isDirectCall: boolean;
}): Promise<{
redirectTo: string;
setCookie: string | undefined;
}>;
}): Promise<
| ErrorOAuth2
| {
status: string;
redirectTo: string;
setCookie: string | undefined;
}
| {
redirectTo: string;
setCookie: string | undefined;
status?: undefined;
}
>;
export declare function handleLoginInternalRedirects({
response,
recipeImplementation,
Expand Down
18 changes: 14 additions & 4 deletions lib/build/recipe/oauth2provider/api/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ async function loginGET({
challenge: loginChallenge,
userContext,
});
if (loginRequest.status === "ERROR") {
return loginRequest;
}
const sessionInfo =
session !== undefined
? await session_1.getSessionInformation(
Expand All @@ -49,23 +52,25 @@ async function loginGET({
const reject = await recipeImplementation.rejectLoginRequest({
challenge: loginChallenge,
error: {
status: "ERROR",
error: "invalid_request",
errorDescription: "max_age cannot be negative",
},
userContext,
});
return { redirectTo: reject.redirectTo, setCookie };
return { status: "REDIRECT", redirectTo: reject.redirectTo, setCookie };
}
} catch (_c) {
const reject = await recipeImplementation.rejectLoginRequest({
challenge: loginChallenge,
error: {
status: "ERROR",
error: "invalid_request",
errorDescription: "max_age must be an integer",
},
userContext,
});
return { redirectTo: reject.redirectTo, setCookie };
return { status: "REDIRECT", redirectTo: reject.redirectTo, setCookie };
}
}
const tenantIdParam = incomingAuthUrlQueryParams.get("tenant_id");
Expand All @@ -86,7 +91,7 @@ async function loginGET({
rememberFor: 3600,
userContext,
});
return { redirectTo: accept.redirectTo, setCookie };
return { status: "REDIRECT", redirectTo: accept.redirectTo, setCookie };
}
if (shouldTryRefresh && promptParam !== "login") {
return {
Expand All @@ -102,15 +107,17 @@ async function loginGET({
const reject = await recipeImplementation.rejectLoginRequest({
challenge: loginChallenge,
error: {
status: "ERROR",
error: "login_required",
errorDescription:
"The Authorization Server requires End-User authentication. Prompt 'none' was requested, but no existing or expired login session was found.",
},
userContext,
});
return { redirectTo: reject.redirectTo, setCookie };
return { status: "REDIRECT", redirectTo: reject.redirectTo, setCookie };
}
return {
status: "REDIRECT",
redirectTo: await recipeImplementation.getFrontendRedirectionURL({
type: "login",
loginChallenge,
Expand Down Expand Up @@ -208,6 +215,9 @@ async function handleLoginInternalRedirects({
isDirectCall: false,
userContext,
});
if ("error" in loginRes) {
return loginRes;
}
response = {
redirectTo: loginRes.redirectTo,
setCookie: mergeSetCookieHeaders(loginRes.setCookie, response.setCookie),
Expand Down
22 changes: 22 additions & 0 deletions lib/build/recipe/oauth2provider/recipeImplementation.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,16 @@ function getRecipeInterface(
{ loginChallenge: input.challenge },
input.userContext
);
if (resp.status !== "OK") {
return {
status: "ERROR",
statusCode: resp.statusCode,
error: resp.error,
errorDescription: resp.errorDescription,
};
}
return {
status: "OK",
challenge: resp.challenge,
client: OAuth2Client_1.OAuth2Client.fromAPIResponse(resp.client),
oidcContext: resp.oidcContext,
Expand Down Expand Up @@ -216,6 +225,7 @@ function getRecipeInterface(
let payloads;
if (input.params.client_id === undefined || typeof input.params.client_id !== "string") {
return {
status: "ERROR",
statusCode: 400,
error: "invalid_request",
errorDescription: "client_id is required and must be a string",
Expand All @@ -240,6 +250,7 @@ function getRecipeInterface(
});
if (clientInfo.status === "ERROR") {
return {
status: "ERROR",
statusCode: 400,
error: clientInfo.error,
errorDescription: clientInfo.errorDescription,
Expand All @@ -249,6 +260,7 @@ function getRecipeInterface(
const user = await __1.getUser(input.session.getUserId());
if (!user) {
return {
status: "ERROR",
statusCode: 400,
error: "invalid_request",
errorDescription: "User deleted",
Expand Down Expand Up @@ -292,13 +304,15 @@ function getRecipeInterface(
);
if (resp.status === "CLIENT_NOT_FOUND_ERROR") {
return {
status: "ERROR",
statusCode: 400,
error: "invalid_request",
errorDescription: "The provided client_id is not valid",
};
}
if (resp.status !== "OK") {
return {
status: "ERROR",
statusCode: resp.statusCode,
error: resp.error,
errorDescription: resp.errorDescription,
Expand Down Expand Up @@ -342,6 +356,7 @@ function getRecipeInterface(
body.iss = await this.getIssuer({ userContext: input.userContext });
if (input.body.grant_type === "password") {
return {
status: "ERROR",
statusCode: 400,
error: "invalid_request",
errorDescription: "Unsupported grant type: password",
Expand All @@ -350,6 +365,7 @@ function getRecipeInterface(
if (input.body.grant_type === "client_credentials") {
if (input.body.client_id === undefined) {
return {
status: "ERROR",
statusCode: 400,
error: "invalid_request",
errorDescription: "client_id is required",
Expand All @@ -366,6 +382,7 @@ function getRecipeInterface(
});
if (clientInfo.status === "ERROR") {
return {
status: "ERROR",
statusCode: 400,
error: clientInfo.error,
errorDescription: clientInfo.errorDescription,
Expand Down Expand Up @@ -406,6 +423,7 @@ function getRecipeInterface(
});
if (clientInfo.status === "ERROR") {
return {
status: "ERROR",
statusCode: 400,
error: clientInfo.error,
errorDescription: clientInfo.errorDescription,
Expand All @@ -415,6 +433,7 @@ function getRecipeInterface(
const user = await __1.getUser(tokenInfo.sub);
if (!user) {
return {
status: "ERROR",
statusCode: 400,
error: "invalid_request",
errorDescription: "User not found",
Expand Down Expand Up @@ -446,6 +465,7 @@ function getRecipeInterface(
);
if (res.status !== "OK") {
return {
status: "ERROR",
statusCode: res.statusCode,
error: res.error,
errorDescription: res.errorDescription,
Expand Down Expand Up @@ -678,6 +698,7 @@ function getRecipeInterface(
);
if (res.status !== "OK") {
return {
status: "ERROR",
statusCode: res.statusCode,
error: res.error,
errorDescription: res.errorDescription,
Expand Down Expand Up @@ -756,6 +777,7 @@ function getRecipeInterface(
);
if ("error" in resp) {
return {
status: "ERROR",
statusCode: resp.statusCode,
error: resp.error,
errorDescription: resp.errorDescription,
Expand Down
12 changes: 11 additions & 1 deletion lib/build/recipe/oauth2provider/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export declare type APIOptions = {
res: BaseResponse;
};
export declare type ErrorOAuth2 = {
status: "ERROR";
error: string;
errorDescription: string;
statusCode?: number;
Expand Down Expand Up @@ -137,7 +138,15 @@ export declare type RecipeInterface = {
}): Promise<{
redirectTo: string;
}>;
getLoginRequest(input: { challenge: string; userContext: UserContext }): Promise<LoginRequest>;
getLoginRequest(input: {
challenge: string;
userContext: UserContext;
}): Promise<
| (LoginRequest & {
status: "OK";
})
| ErrorOAuth2
>;
acceptLoginRequest(input: {
challenge: string;
acr?: string;
Expand Down Expand Up @@ -414,6 +423,7 @@ export declare type APIInterface = {
status: "OK";
info: LoginInfo;
}
| ErrorOAuth2
| GeneralErrorResponse
>);
userInfoGET:
Expand Down
12 changes: 11 additions & 1 deletion lib/ts/recipe/oauth2provider/api/implementation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ export default function getAPIImplementation(): APIInterface {
isDirectCall: true,
userContext,
});

if ("error" in response) {
return response;
}

const respAfterInternalRedirects = await handleLoginInternalRedirects({
response,
cookie: options.req.getHeaderValue("cookie"),
Expand Down Expand Up @@ -75,11 +80,16 @@ export default function getAPIImplementation(): APIInterface {
});
},
loginInfoGET: async ({ loginChallenge, options, userContext }) => {
const { client } = await options.recipeImplementation.getLoginRequest({
const loginRes = await options.recipeImplementation.getLoginRequest({
challenge: loginChallenge,
userContext,
});

if (loginRes.status === "ERROR") {
return loginRes;
}
const { client } = loginRes;

return {
status: "OK",
info: {
Expand Down
20 changes: 16 additions & 4 deletions lib/ts/recipe/oauth2provider/api/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ export async function loginGET({
userContext,
});

if (loginRequest.status === "ERROR") {
return loginRequest;
}

const sessionInfo = session !== undefined ? await getSessionInformation(session?.getHandle()) : undefined;
if (!sessionInfo) {
session = undefined;
Expand All @@ -47,23 +51,25 @@ export async function loginGET({
const reject = await recipeImplementation.rejectLoginRequest({
challenge: loginChallenge,
error: {
status: "ERROR",
error: "invalid_request",
errorDescription: "max_age cannot be negative",
},
userContext,
});
return { redirectTo: reject.redirectTo, setCookie };
return { status: "REDIRECT", redirectTo: reject.redirectTo, setCookie };
}
} catch {
const reject = await recipeImplementation.rejectLoginRequest({
challenge: loginChallenge,
error: {
status: "ERROR",
error: "invalid_request",
errorDescription: "max_age must be an integer",
},
userContext,
});
return { redirectTo: reject.redirectTo, setCookie };
return { status: "REDIRECT", redirectTo: reject.redirectTo, setCookie };
}
}
const tenantIdParam = incomingAuthUrlQueryParams.get("tenant_id");
Expand All @@ -84,7 +90,7 @@ export async function loginGET({
rememberFor: 3600,
userContext,
});
return { redirectTo: accept.redirectTo, setCookie };
return { status: "REDIRECT", redirectTo: accept.redirectTo, setCookie };
}

if (shouldTryRefresh && promptParam !== "login") {
Expand All @@ -101,16 +107,18 @@ export async function loginGET({
const reject = await recipeImplementation.rejectLoginRequest({
challenge: loginChallenge,
error: {
status: "ERROR",
error: "login_required",
errorDescription:
"The Authorization Server requires End-User authentication. Prompt 'none' was requested, but no existing or expired login session was found.",
},
userContext,
});
return { redirectTo: reject.redirectTo, setCookie };
return { status: "REDIRECT", redirectTo: reject.redirectTo, setCookie };
}

return {
status: "REDIRECT",
redirectTo: await recipeImplementation.getFrontendRedirectionURL({
type: "login",
loginChallenge,
Expand Down Expand Up @@ -226,6 +234,10 @@ export async function handleLoginInternalRedirects({
userContext,
});

if ("error" in loginRes) {
return loginRes;
}

response = {
redirectTo: loginRes.redirectTo,
setCookie: mergeSetCookieHeaders(loginRes.setCookie, response.setCookie),
Expand Down
Loading

0 comments on commit e95511a

Please sign in to comment.