Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
porcellus committed Sep 20, 2024
1 parent d8b0c40 commit 374f066
Show file tree
Hide file tree
Showing 34 changed files with 762 additions and 760 deletions.
15 changes: 0 additions & 15 deletions lib/build/combinedRemoteJWKSet.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion lib/build/querier.d.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

68 changes: 9 additions & 59 deletions lib/build/querier.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 0 additions & 9 deletions lib/build/recipe/jwt/api/implementation.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,6 @@ function getAPIImplementation() {
if (resp.validityInSeconds !== undefined) {
options.res.setHeader("Cache-Control", `max-age=${resp.validityInSeconds}, must-revalidate`, false);
}
const oauth2Provider = require("../../oauth2provider/recipe").default.getInstance();
// TODO: dirty hack until we get core support
if (oauth2Provider !== undefined) {
const oauth2JWKSRes = await fetch("http://localhost:4444/.well-known/jwks.json");
if (oauth2JWKSRes.ok) {
const oauth2RespBody = await oauth2JWKSRes.json();
resp.keys = resp.keys.concat(oauth2RespBody.keys);
}
}
return {
keys: resp.keys,
};
Expand Down
16 changes: 14 additions & 2 deletions lib/build/recipe/oauth2client/api/implementation.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,20 @@ const session_1 = __importDefault(require("../../session"));
function getAPIInterface() {
return {
signInPOST: async function (input) {
const { options, tenantId, userContext } = input;
const providerConfig = await options.recipeImplementation.getProviderConfig({ userContext });
const { options, tenantId, userContext, clientId } = input;
let normalisedClientId = clientId;
if (normalisedClientId === undefined) {
if (options.config.providerConfigs.length > 1) {
throw new Error(
"Should never come here: clientId is undefined and there are multiple providerConfigs"
);
}
normalisedClientId = options.config.providerConfigs[0].clientId;
}
const providerConfig = await options.recipeImplementation.getProviderConfig({
clientId: normalisedClientId,
userContext,
});
let oAuthTokensToUse = {};
if ("redirectURIInfo" in input && input.redirectURIInfo !== undefined) {
oAuthTokensToUse = await options.recipeImplementation.exchangeAuthCodeForOAuthTokens({
Expand Down
7 changes: 7 additions & 0 deletions lib/build/recipe/oauth2client/api/signin.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ async function signInAPI(apiImplementation, tenantId, options, userContext) {
const bodyParams = await options.req.getJSONBody();
let redirectURIInfo;
let oAuthTokens;
if (bodyParams.clientId === undefined && options.config.providerConfigs.length > 1) {
throw new error_1.default({
type: error_1.default.BAD_INPUT_ERROR,
message: "Please provide the clientId in request body",
});
}
if (bodyParams.redirectURIInfo !== undefined) {
if (bodyParams.redirectURIInfo.redirectURI === undefined) {
throw new error_1.default({
Expand Down Expand Up @@ -59,6 +65,7 @@ async function signInAPI(apiImplementation, tenantId, options, userContext) {
}
let result = await apiImplementation.signInPOST({
tenantId,
clientId: bodyParams.clientId,
redirectURIInfo,
oAuthTokens,
options,
Expand Down
1 change: 1 addition & 0 deletions lib/build/recipe/oauth2client/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export default class Wrapper {
redirectURIQueryParams: any;
pkceCodeVerifier?: string | undefined;
},
clientId?: string,
userContext?: Record<string, any>
): Promise<import("./types").OAuthTokenResponse>;
static getUserInfo(
Expand Down
19 changes: 17 additions & 2 deletions lib/build/recipe/oauth2client/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,22 @@ var __importDefault =
Object.defineProperty(exports, "__esModule", { value: true });
exports.getUserInfo = exports.exchangeAuthCodeForOAuthTokens = exports.init = void 0;
const utils_1 = require("../../utils");
const jwt_1 = require("../session/jwt");
const recipe_1 = __importDefault(require("./recipe"));
class Wrapper {
static async exchangeAuthCodeForOAuthTokens(redirectURIInfo, userContext) {
const recipeInterfaceImpl = recipe_1.default.getInstanceOrThrowError().recipeInterfaceImpl;
static async exchangeAuthCodeForOAuthTokens(redirectURIInfo, clientId, userContext) {
let normalisedClientId = clientId;
const instance = recipe_1.default.getInstanceOrThrowError();
const recipeInterfaceImpl = instance.recipeInterfaceImpl;
const normalisedUserContext = utils_1.getUserContext(userContext);
if (normalisedClientId === undefined) {
if (instance.config.providerConfigs.length > 1) {
throw new Error("clientId is required if there are more than one provider configs defined");
}
normalisedClientId = instance.config.providerConfigs[0].clientId;
}
const providerConfig = await recipeInterfaceImpl.getProviderConfig({
clientId: normalisedClientId,
userContext: normalisedUserContext,
});
return await recipeInterfaceImpl.exchangeAuthCodeForOAuthTokens({
Expand All @@ -38,7 +48,12 @@ class Wrapper {
static async getUserInfo(oAuthTokens, userContext) {
const recipeInterfaceImpl = recipe_1.default.getInstanceOrThrowError().recipeInterfaceImpl;
const normalisedUserContext = utils_1.getUserContext(userContext);
if (oAuthTokens.access_token === undefined) {
throw new Error("access_token is required to get user info");
}
const preparseJWTInfo = jwt_1.parseJWTWithoutSignatureVerification(oAuthTokens.access_token);
const providerConfig = await recipeInterfaceImpl.getProviderConfig({
clientId: preparseJWTInfo.payload.client_id,
userContext: normalisedUserContext,
});
return await recipe_1.default.getInstanceOrThrowError().recipeInterfaceImpl.getUserInfo({
Expand Down
19 changes: 12 additions & 7 deletions lib/build/recipe/oauth2client/recipeImplementation.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const __1 = require("../..");
const logger_1 = require("../../logger");
const jose_1 = require("jose");
function getRecipeImplementation(_querier, config) {
let providerConfigWithOIDCInfo = null;
let providerConfigsWithOIDCInfo = {};
return {
signIn: async function ({ userId, tenantId, userContext, oAuthTokens, rawUserInfo }) {
const user = await __1.getUser(userId, userContext);
Expand All @@ -26,11 +26,16 @@ function getRecipeImplementation(_querier, config) {
rawUserInfo,
};
},
getProviderConfig: async function () {
if (providerConfigWithOIDCInfo !== null) {
return providerConfigWithOIDCInfo;
getProviderConfig: async function ({ clientId }) {
if (providerConfigsWithOIDCInfo[clientId] !== null) {
return providerConfigsWithOIDCInfo[clientId];
}
const oidcInfo = await thirdpartyUtils_1.getOIDCDiscoveryInfo(config.providerConfig.oidcDiscoveryEndpoint);
const providerConfig = config.providerConfigs.find(
(providerConfig) => providerConfig.clientId === clientId
);
const oidcInfo = await thirdpartyUtils_1.getOIDCDiscoveryInfo(
config.providerConfigs[0].oidcDiscoveryEndpoint
);
if (oidcInfo.authorization_endpoint === undefined) {
throw new Error("Failed to authorization_endpoint from the oidcDiscoveryEndpoint.");
}
Expand All @@ -43,13 +48,13 @@ function getRecipeImplementation(_querier, config) {
if (oidcInfo.jwks_uri === undefined) {
throw new Error("Failed to jwks_uri from the oidcDiscoveryEndpoint.");
}
providerConfigWithOIDCInfo = Object.assign(Object.assign({}, config.providerConfig), {
providerConfigsWithOIDCInfo[clientId] = Object.assign(Object.assign({}, providerConfig), {
authorizationEndpoint: oidcInfo.authorization_endpoint,
tokenEndpoint: oidcInfo.token_endpoint,
userInfoEndpoint: oidcInfo.userinfo_endpoint,
jwksURI: oidcInfo.jwks_uri,
});
return providerConfigWithOIDCInfo;
return providerConfigsWithOIDCInfo[clientId];
},
exchangeAuthCodeForOAuthTokens: async function ({ providerConfig, redirectURIInfo }) {
if (providerConfig.tokenEndpoint === undefined) {
Expand Down
7 changes: 4 additions & 3 deletions lib/build/recipe/oauth2client/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export declare type OAuthTokenResponse = {
token_type: string;
};
export declare type TypeInput = {
providerConfig: ProviderConfigInput;
providerConfigs: ProviderConfigInput[];
override?: {
functions?: (
originalImplementation: RecipeInterface,
Expand All @@ -50,7 +50,7 @@ export declare type TypeInput = {
};
};
export declare type TypeNormalisedInput = {
providerConfig: ProviderConfigInput;
providerConfigs: ProviderConfigInput[];
override: {
functions: (
originalImplementation: RecipeInterface,
Expand All @@ -60,7 +60,7 @@ export declare type TypeNormalisedInput = {
};
};
export declare type RecipeInterface = {
getProviderConfig(input: { userContext: UserContext }): Promise<ProviderConfigWithOIDCInfo>;
getProviderConfig(input: { clientId: string; userContext: UserContext }): Promise<ProviderConfigWithOIDCInfo>;
signIn(input: {
userId: string;
oAuthTokens: OAuthTokens;
Expand Down Expand Up @@ -116,6 +116,7 @@ export declare type APIInterface = {
signInPOST: (
input: {
tenantId: string;
clientId?: string;
options: APIOptions;
userContext: UserContext;
} & (
Expand Down
25 changes: 12 additions & 13 deletions lib/build/recipe/oauth2client/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,19 @@
Object.defineProperty(exports, "__esModule", { value: true });
exports.validateAndNormaliseUserInput = void 0;
function validateAndNormaliseUserInput(_appInfo, config) {
if (config === undefined || config.providerConfig === undefined) {
throw new Error("Please pass providerConfig argument in the OAuth2Client recipe.");
if (config === undefined || config.providerConfigs === undefined) {
throw new Error("Please pass providerConfigs argument in the OAuth2Client recipe.");
}
if (config.providerConfig.clientId === undefined) {
throw new Error("Please pass clientId argument in the OAuth2Client providerConfig.");
if (config.providerConfigs.some((providerConfig) => providerConfig.clientId === undefined)) {
throw new Error("Please pass clientId for all providerConfigs.");
}
// TODO: Decide on the prefix and also if we will allow users to customise clientIds
// if (!config.providerConfig.clientId.startsWith("supertokens_")) {
// throw new Error(
// `Only Supertokens OAuth ClientIds are supported in the OAuth2Client recipe. For any other OAuth Clients use the thirdparty recipe.`
// );
// }
if (config.providerConfig.oidcDiscoveryEndpoint === undefined) {
throw new Error("Please pass oidcDiscoveryEndpoint argument in the OAuth2Client providerConfig.");
if (!config.providerConfigs.every((providerConfig) => providerConfig.clientId.startsWith("supertokens_"))) {
throw new Error(
`Only Supertokens OAuth ClientIds are supported in the OAuth2Client recipe. For any other OAuth Clients use the ThirdParty recipe.`
);
}
if (config.providerConfigs.some((providerConfig) => providerConfig.oidcDiscoveryEndpoint === undefined)) {
throw new Error("Please pass oidcDiscoveryEndpoint for all providerConfigs.");
}
let override = Object.assign(
{
Expand All @@ -39,7 +38,7 @@ function validateAndNormaliseUserInput(_appInfo, config) {
config === null || config === void 0 ? void 0 : config.override
);
return {
providerConfig: config.providerConfig,
providerConfigs: config.providerConfigs,
override,
};
}
Expand Down
Loading

0 comments on commit 374f066

Please sign in to comment.