Skip to content

Commit

Permalink
fix: boxy dashboard and flag to include tp provider in non-public ten…
Browse files Browse the repository at this point in the history
…ants
  • Loading branch information
sattvikc committed Jul 23, 2024
1 parent 82dd47e commit 8ad3edb
Show file tree
Hide file tree
Showing 15 changed files with 217 additions and 111 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ async function createOrUpdateThirdPartyConfig(_, tenantId, options, userContext)
_a !== void 0
? _a
: [];
for (const provider of staticProviders) {
for (const provider of staticProviders.filter(
(provider) => provider.includeInNonPublicTenantsByDefault === true
)) {
await multitenancy_1.default.createOrUpdateThirdPartyConfig(
tenantId,
{
Expand All @@ -42,58 +44,56 @@ async function createOrUpdateThirdPartyConfig(_, tenantId, options, userContext)
}
}
if (providerConfig.thirdPartyId.startsWith("boxy-saml")) {
// boxy stuff here
const boxyURL = providerConfig.clients[0].additionalConfig.boxyURL;
const boxyAPIKey = providerConfig.clients[0].additionalConfig.boxyAPIKey;
providerConfig.clients[0].additionalConfig.boxyAPIKey = undefined;
const requestBody = {
name: "",
label: "",
description: "",
tenant: `${tenantId}-providerConfig.thirdPartyId`,
product: "supertokens",
defaultRedirectUrl: providerConfig.clients[0].additionalConfig.redirectURLs[0],
forceAuthn: false,
encodedRawMetadata: "",
redirectUrl: JSON.stringify(providerConfig.clients[0].additionalConfig.redirectURLs),
metadataUrl: providerConfig.clients[0].additionalConfig.samlURL || "",
};
const normalisedDomain = new normalisedURLDomain_1.default(boxyURL);
const normalisedBasePath = new normalisedURLPath_1.default(boxyURL);
const connectionsPath = new normalisedURLPath_1.default("/api/v1/saml/config");
const resp = await utils_1.doPostRequest(
normalisedDomain.getAsStringDangerous() +
normalisedBasePath.getAsStringDangerous() +
connectionsPath.getAsStringDangerous(),
requestBody,
{
Authorization: `Api-Key ${boxyAPIKey}`,
}
);
if (resp.status !== 200) {
if (resp.status === 401) {
if (boxyAPIKey) {
const requestBody = {
name: "",
label: "",
description: "",
tenant:
providerConfig.clients[0].additionalConfig.boxyTenant ||
`${tenantId}-${providerConfig.thirdPartyId}`,
product: providerConfig.clients[0].additionalConfig.boxyProduct || "supertokens",
defaultRedirectUrl: providerConfig.clients[0].additionalConfig.redirectURLs[0],
forceAuthn: false,
encodedRawMetadata: providerConfig.clients[0].additionalConfig.samlXML
? Buffer.from(providerConfig.clients[0].additionalConfig.samlXML).toString("base64")
: "",
redirectUrl: JSON.stringify(providerConfig.clients[0].additionalConfig.redirectURLs),
metadataUrl: providerConfig.clients[0].additionalConfig.samlURL || "",
};
const normalisedDomain = new normalisedURLDomain_1.default(boxyURL);
const normalisedBasePath = new normalisedURLPath_1.default(boxyURL);
const connectionsPath = new normalisedURLPath_1.default("/api/v1/saml/config");
const resp = await utils_1.doPostRequest(
normalisedDomain.getAsStringDangerous() +
normalisedBasePath.getAsStringDangerous() +
connectionsPath.getAsStringDangerous(),
requestBody,
{
Authorization: `Api-Key ${boxyAPIKey}`,
}
);
if (resp.status !== 200) {
if (resp.status === 401) {
return {
status: "BOXY_ERROR",
message: "Invalid API Key",
};
}
return {
status: "BOXY_ERROR",
message: "Invalid API Key",
message: resp.stringResponse,
};
}
return {
status: "BOXY_ERROR",
message: resp.stringResponse,
};
}
if (resp.jsonResponse === undefined) {
throw new Error("should never happen");
if (resp.jsonResponse === undefined) {
throw new Error("should never happen");
}
providerConfig.clients[0].clientId = resp.jsonResponse.clientID;
providerConfig.clients[0].clientSecret = resp.jsonResponse.clientSecret;
}
providerConfig.clients[0].clientId = resp.jsonResponse.clientID;
providerConfig.clients[0].clientSecret = resp.jsonResponse.clientSecret;
const thirdPartyRes = await multitenancy_1.default.createOrUpdateThirdPartyConfig(
tenantId,
providerConfig,
undefined,
userContext
);
return thirdPartyRes;
}
const thirdPartyRes = await multitenancy_1.default.createOrUpdateThirdPartyConfig(
tenantId,
Expand Down
4 changes: 3 additions & 1 deletion lib/build/recipe/dashboard/api/multitenancy/getTenantInfo.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ const utils_1 = require("./utils");
const configUtils_1 = require("../../../thirdparty/providers/configUtils");
const normalisedURLPath_1 = __importDefault(require("../../../../normalisedURLPath"));
const querier_1 = require("../../../../querier");
const constants_1 = require("../../../multitenancy/constants");
async function getTenantInfo(_, tenantId, options, userContext) {
var _a, _b;
let tenantRes = await multitenancy_1.default.getTenant(tenantId, userContext);
Expand Down Expand Up @@ -54,7 +55,8 @@ async function getTenantInfo(_, tenantId, options, userContext) {
: [];
const mergedProvidersFromCoreAndStatic = configUtils_1.mergeProvidersFromCoreAndStatic(
providersFromCore,
staticProviders
staticProviders,
tenantId === constants_1.DEFAULT_TENANT_ID
);
let querier = querier_1.Querier.getNewInstanceOrThrowError(options.recipeId);
let coreConfig = await querier.sendGetRequest(
Expand Down
50 changes: 45 additions & 5 deletions lib/build/recipe/dashboard/api/multitenancy/getThirdPartyConfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
const multitenancy_1 = __importDefault(require("../../../multitenancy"));
const recipe_1 = __importDefault(require("../../../multitenancy/recipe"));
const configUtils_1 = require("../../../thirdparty/providers/configUtils");
const normalisedURLDomain_1 = __importDefault(require("../../../../normalisedURLDomain"));
const normalisedURLPath_1 = __importDefault(require("../../../../normalisedURLPath"));
const utils_1 = require("../../../thirdparty/providers/utils");
async function getThirdPartyConfig(_, tenantId, options, userContext) {
var _a, _b, _c, _d;
var _a, _b, _c, _d, _e;
let tenantRes = await multitenancy_1.default.getTenant(tenantId, userContext);
if (tenantRes === undefined) {
return {
Expand Down Expand Up @@ -136,7 +139,8 @@ async function getThirdPartyConfig(_, tenantId, options, userContext) {
}
let mergedProvidersFromCoreAndStatic = configUtils_1.mergeProvidersFromCoreAndStatic(
providersFromCore,
staticProviders
staticProviders,
true
);
if (mergedProvidersFromCoreAndStatic.length !== 1) {
throw new Error("should never come here!");
Expand Down Expand Up @@ -171,9 +175,9 @@ async function getThirdPartyConfig(_, tenantId, options, userContext) {
client.clientType,
userContext
);
const _e = providerInstance.config,
{ clientId, clientSecret, clientType, scope, additionalConfig, forcePKCE } = _e,
commonConfig = __rest(_e, [
const _f = providerInstance.config,
{ clientId, clientSecret, clientType, scope, additionalConfig, forcePKCE } = _f,
commonConfig = __rest(_f, [
"clientId",
"clientSecret",
"clientType",
Expand Down Expand Up @@ -233,6 +237,42 @@ async function getThirdPartyConfig(_, tenantId, options, userContext) {
)
);
}
// fill in boxy info from boxy instance
if (thirdPartyId.startsWith("boxy-saml")) {
const boxyAPIKey = options.req.getKeyValueFromQuery("boxyAPIKey");
if (boxyAPIKey) {
if (finalClients[0].clientId !== "") {
const boxyURL = (_e = finalClients[0].additionalConfig) === null || _e === void 0 ? void 0 : _e.boxyURL;
const normalisedDomain = new normalisedURLDomain_1.default(boxyURL);
const normalisedBasePath = new normalisedURLPath_1.default(boxyURL);
const connectionsPath = new normalisedURLPath_1.default("/api/v1/saml/config");
const resp = await utils_1.doGetRequest(
normalisedDomain.getAsStringDangerous() +
normalisedBasePath.getAsStringDangerous() +
connectionsPath.getAsStringDangerous(),
{
clientID: finalClients[0].clientId,
},
{
Authorization: `Api-Key ${boxyAPIKey}`,
}
);
if (resp.status === 200) {
if (resp.jsonResponse === undefined) {
throw new Error("should never happen");
}
finalClients[0].additionalConfig = Object.assign(
Object.assign({}, finalClients[0].additionalConfig),
{
redirectURLs: resp.jsonResponse.redirectUrl,
boxyTenant: resp.jsonResponse.tenant,
boxyProduct: resp.jsonResponse.product,
}
);
}
}
}
}
return {
status: "OK",
providerConfig: Object.assign(Object.assign({}, commonProviderConfig), {
Expand Down
4 changes: 3 additions & 1 deletion lib/build/recipe/multitenancy/api/implementation.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
Object.defineProperty(exports, "__esModule", { value: true });
const utils_1 = require("../../multitenancy/utils");
const configUtils_1 = require("../../thirdparty/providers/configUtils");
const constants_1 = require("../constants");
function getAPIInterface() {
return {
loginMethodsGET: async function ({ tenantId, clientType, options, userContext }) {
Expand All @@ -16,7 +17,8 @@ function getAPIInterface() {
const providerConfigsFromCore = tenantConfigRes.thirdParty.providers;
const mergedProviders = configUtils_1.mergeProvidersFromCoreAndStatic(
providerConfigsFromCore,
providerInputsFromStatic
providerInputsFromStatic,
tenantId === constants_1.DEFAULT_TENANT_ID
);
const finalProviderList = [];
for (const providerInput of mergedProviders) {
Expand Down
3 changes: 2 additions & 1 deletion lib/build/recipe/thirdparty/providers/configUtils.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,6 @@ export declare function findAndCreateProviderInstance(
export declare function mergeConfig(staticConfig: ProviderConfig, coreConfig: ProviderConfig): ProviderConfig;
export declare function mergeProvidersFromCoreAndStatic(
providerConfigsFromCore: ProviderConfig[],
providerInputsFromStatic: ProviderInput[]
providerInputsFromStatic: ProviderInput[],
includeAllProviders: boolean
): ProviderInput[];
6 changes: 4 additions & 2 deletions lib/build/recipe/thirdparty/providers/configUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,10 +108,12 @@ function mergeConfig(staticConfig, coreConfig) {
return result;
}
exports.mergeConfig = mergeConfig;
function mergeProvidersFromCoreAndStatic(providerConfigsFromCore, providerInputsFromStatic) {
function mergeProvidersFromCoreAndStatic(providerConfigsFromCore, providerInputsFromStatic, includeAllProviders) {
const mergedProviders = [];
if (providerConfigsFromCore.length === 0) {
for (const config of providerInputsFromStatic) {
for (const config of providerInputsFromStatic.filter(
(config) => config.includeInNonPublicTenantsByDefault === true || includeAllProviders === true
)) {
mergedProviders.push(config);
}
} else {
Expand Down
4 changes: 3 additions & 1 deletion lib/build/recipe/thirdparty/recipeImplementation.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ const recipeUserId_1 = __importDefault(require("../../recipeUserId"));
const __1 = require("../..");
const user_1 = require("../../user");
const authUtils_1 = require("../../authUtils");
const constants_1 = require("../multitenancy/constants");
function getRecipeImplementation(querier, providers) {
return {
manuallyCreateOrUpdateUser: async function ({
Expand Down Expand Up @@ -133,7 +134,8 @@ function getRecipeImplementation(querier, providers) {
}
const mergedProviders = configUtils_1.mergeProvidersFromCoreAndStatic(
tenantConfig.thirdParty.providers,
providers
providers,
tenantId === constants_1.DEFAULT_TENANT_ID
);
const provider = await configUtils_1.findAndCreateProviderInstance(
mergedProviders,
Expand Down
1 change: 1 addition & 0 deletions lib/build/recipe/thirdparty/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ export declare type ProviderConfig = CommonProviderConfig & {
};
export declare type ProviderInput = {
config: ProviderConfig;
includeInNonPublicTenantsByDefault?: boolean;
override?: (originalImplementation: TypeProvider) => TypeProvider;
};
export declare type TypeInputSignInAndUp = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,9 @@ export default async function createOrUpdateThirdPartyConfig(
// This means that the tenant was using the static list of providers, we need to add them all before adding the new one
const mtRecipe = MultitenancyRecipe.getInstance();
const staticProviders = mtRecipe?.staticThirdPartyProviders ?? [];
for (const provider of staticProviders) {
for (const provider of staticProviders.filter(
(provider) => provider.includeInNonPublicTenantsByDefault === true
)) {
await Multitenancy.createOrUpdateThirdPartyConfig(
tenantId,
{
Expand All @@ -64,67 +66,62 @@ export default async function createOrUpdateThirdPartyConfig(
}

if (providerConfig.thirdPartyId.startsWith("boxy-saml")) {
// boxy stuff here
const boxyURL: string = providerConfig.clients[0].additionalConfig.boxyURL;
const boxyAPIKey: string = providerConfig.clients[0].additionalConfig.boxyAPIKey;

providerConfig.clients[0].additionalConfig.boxyAPIKey = undefined;

const requestBody = {
name: "",
label: "",
description: "",
tenant: `${tenantId}-providerConfig.thirdPartyId`,
product: "supertokens",
defaultRedirectUrl: providerConfig.clients[0].additionalConfig.redirectURLs[0],
forceAuthn: false,
encodedRawMetadata: "",
redirectUrl: JSON.stringify(providerConfig.clients[0].additionalConfig.redirectURLs),
metadataUrl: providerConfig.clients[0].additionalConfig.samlURL || "",
};
if (boxyAPIKey) {
const requestBody = {
name: "",
label: "",
description: "",
tenant:
providerConfig.clients[0].additionalConfig.boxyTenant ||
`${tenantId}-${providerConfig.thirdPartyId}`,
product: providerConfig.clients[0].additionalConfig.boxyProduct || "supertokens",
defaultRedirectUrl: providerConfig.clients[0].additionalConfig.redirectURLs[0],
forceAuthn: false,
encodedRawMetadata: providerConfig.clients[0].additionalConfig.samlXML
? Buffer.from(providerConfig.clients[0].additionalConfig.samlXML).toString("base64")
: "",
redirectUrl: JSON.stringify(providerConfig.clients[0].additionalConfig.redirectURLs),
metadataUrl: providerConfig.clients[0].additionalConfig.samlURL || "",
};

const normalisedDomain = new NormalisedURLDomain(boxyURL);
const normalisedBasePath = new NormalisedURLPath(boxyURL);
const connectionsPath = new NormalisedURLPath("/api/v1/saml/config");
const normalisedDomain = new NormalisedURLDomain(boxyURL);
const normalisedBasePath = new NormalisedURLPath(boxyURL);
const connectionsPath = new NormalisedURLPath("/api/v1/saml/config");

const resp = await doPostRequest(
normalisedDomain.getAsStringDangerous() +
normalisedBasePath.getAsStringDangerous() +
connectionsPath.getAsStringDangerous(),
requestBody,
{
Authorization: `Api-Key ${boxyAPIKey}`,
}
);
const resp = await doPostRequest(
normalisedDomain.getAsStringDangerous() +
normalisedBasePath.getAsStringDangerous() +
connectionsPath.getAsStringDangerous(),
requestBody,
{
Authorization: `Api-Key ${boxyAPIKey}`,
}
);

if (resp.status !== 200) {
if (resp.status === 401) {
if (resp.status !== 200) {
if (resp.status === 401) {
return {
status: "BOXY_ERROR",
message: "Invalid API Key",
};
}
return {
status: "BOXY_ERROR",
message: "Invalid API Key",
message: resp.stringResponse,
};
}
return {
status: "BOXY_ERROR",
message: resp.stringResponse,
};
}

if (resp.jsonResponse === undefined) {
throw new Error("should never happen");
}

providerConfig.clients[0].clientId = resp.jsonResponse.clientID;
providerConfig.clients[0].clientSecret = resp.jsonResponse.clientSecret;

const thirdPartyRes = await Multitenancy.createOrUpdateThirdPartyConfig(
tenantId,
providerConfig,
undefined,
userContext
);
if (resp.jsonResponse === undefined) {
throw new Error("should never happen");
}

return thirdPartyRes;
providerConfig.clients[0].clientId = resp.jsonResponse.clientID;
providerConfig.clients[0].clientSecret = resp.jsonResponse.clientSecret;
}
}

const thirdPartyRes = await Multitenancy.createOrUpdateThirdPartyConfig(
Expand Down
Loading

0 comments on commit 8ad3edb

Please sign in to comment.