Added Microsoft Tenant ID in OAuth option (#224)

* added ms tenant id

* fixed types
This commit is contained in:
Zai Shi 2024-09-05 23:10:31 +02:00 committed by GitHub
parent 5cd25044a6
commit f60508031e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 32 additions and 5 deletions

View File

@ -0,0 +1,2 @@
-- AlterTable
ALTER TABLE "StandardOAuthProviderConfig" ADD COLUMN "microsoftTenantId" TEXT;

View File

@ -566,7 +566,9 @@ model StandardOAuthProviderConfig {
// optional extra parameters for specific oauth providers
// Facebook business integration requires a config_id
facebookConfigId String?
facebookConfigId String?
// Microsoft organizational directory (tenant)
microsoftTenantId String?
@@id([projectConfigId, id])
}

View File

@ -72,6 +72,7 @@ export const internalProjectsCrudHandlers = createLazyProxy(() => createCrudHand
clientId: item.client_id ?? throwErr('client_id is required'),
clientSecret: item.client_secret ?? throwErr('client_secret is required'),
facebookConfigId: item.facebook_config_id,
microsoftTenantId: item.microsoft_tenant_id,
}
} : undefined,
}))

View File

@ -194,6 +194,7 @@ export const projectsCrudHandlers = createLazyProxy(() => createCrudHandlers(pro
clientId: providerUpdate.client_id ?? throwErr('client_id is required'),
clientSecret: providerUpdate.client_secret ?? throwErr('client_secret is required'),
facebookConfigId: providerUpdate.facebook_config_id,
microsoftTenantId: providerUpdate.microsoft_tenant_id,
},
},
};
@ -227,6 +228,7 @@ export const projectsCrudHandlers = createLazyProxy(() => createCrudHandlers(pro
clientId: provider.update.client_id ?? throwErr('client_id is required'),
clientSecret: provider.update.client_secret ?? throwErr('client_secret is required'),
facebookConfigId: provider.update.facebook_config_id,
microsoftTenantId: provider.update.microsoft_tenant_id,
},
},
};

View File

@ -68,6 +68,7 @@ export function projectPrismaToCrud(
client_id?: string,
client_secret?: string ,
facebook_config_id?: string,
microsoft_tenant_id?: string,
}[] => {
if (provider.proxiedOAuthConfig) {
return [{
@ -83,6 +84,7 @@ export function projectPrismaToCrud(
client_id: provider.standardOAuthConfig.clientId,
client_secret: provider.standardOAuthConfig.clientSecret,
facebook_config_id: provider.standardOAuthConfig.facebookConfigId ?? undefined,
microsoft_tenant_id: provider.standardOAuthConfig.microsoftTenantId ?? undefined,
}];
} else {
throw new StackAssertionError(`Exactly one of the provider configs should be set on provider config '${provider.id}' of project '${prisma.id}'`, { prisma });

View File

@ -51,7 +51,8 @@ export async function getProvider(provider: ProjectsCrud['Admin']['Read']['confi
return await _providers[provider.id].create({
clientId: provider.client_id || throwErr("Client ID is required for standard providers"),
clientSecret: provider.client_secret || throwErr("Client secret is required for standard providers"),
facebookConfigId: provider.facebook_config_id
facebookConfigId: provider.facebook_config_id,
microsoftTenantId: provider.microsoft_tenant_id,
});
}
}

View File

@ -12,11 +12,12 @@ export class MicrosoftProvider extends OAuthBaseProvider {
static async create(options: {
clientId: string,
clientSecret: string,
microsoftTenantId?: string,
}) {
return new MicrosoftProvider(...await OAuthBaseProvider.createConstructorArgs({
issuer: "https://login.microsoftonline.com",
authorizationEndpoint: "https://login.microsoftonline.com/consumers/oauth2/v2.0/authorize",
tokenEndpoint: "https://login.microsoftonline.com/consumers/oauth2/v2.0/token",
issuer: `https://login.microsoftonline.com${"/" + options.microsoftTenantId || ""}`,
authorizationEndpoint: `https://login.microsoftonline.com/${options.microsoftTenantId || 'consumers'}/oauth2/v2.0/authorize`,
tokenEndpoint: `https://login.microsoftonline.com/${options.microsoftTenantId || 'consumers'}/oauth2/v2.0/token`,
redirectUri: getEnvVariable("STACK_BASE_URL") + "/api/v1/auth/oauth/callback/microsoft",
baseScope: "User.Read",
...options,

View File

@ -42,6 +42,7 @@ export const providerFormSchema = yup.object({
otherwise: (schema) => schema.optional()
}),
facebookConfigId: yup.string().optional(),
microsoftTenantId: yup.string().optional(),
});
export type ProviderFormValues = yup.InferType<typeof providerFormSchema>
@ -53,6 +54,7 @@ export function ProviderSettingDialog(props: Props & { open: boolean, onClose: (
clientId: (props.provider as any)?.clientId ?? "",
clientSecret: (props.provider as any)?.clientSecret ?? "",
facebookConfigId: (props.provider as any)?.facebookConfigId ?? "",
microsoftTenantId: (props.provider as any)?.microsoftTenantId ?? "",
};
const onSubmit = async (values: ProviderFormValues) => {
@ -66,6 +68,7 @@ export function ProviderSettingDialog(props: Props & { open: boolean, onClose: (
clientId: values.clientId || "",
clientSecret: values.clientSecret || "",
facebookConfigId: values.facebookConfigId,
microsoftTenantId: values.microsoftTenantId,
});
}
};
@ -130,6 +133,15 @@ export function ProviderSettingDialog(props: Props & { open: boolean, onClose: (
placeholder="Facebook Config ID"
/>
)}
{props.id === 'microsoft' && (
<InputField
control={form.control}
name="microsoftTenantId"
label="Tenant ID (required if you are using the organizational directory)"
placeholder="Tenant ID"
/>
)}
</>
)}
</>

View File

@ -15,6 +15,7 @@ const oauthProviderSchema = yupObject({
// extra params
facebook_config_id: yupString().optional().meta({ openapiField: { description: 'This parameter is the configuration id for Facebook business login (for things like ads and marketing).' } }),
microsoft_tenant_id: yupString().optional().meta({ openapiField: { description: 'This parameter is the Microsoft tenant id for Microsoft directory' } }),
});
const enabledOAuthProviderSchema = yupObject({

View File

@ -2006,6 +2006,7 @@ class _StackAdminAppImpl<HasTokenStore extends boolean, ProjectId extends string
clientId: p.client_id ?? throwErr("Client ID is missing"),
clientSecret: p.client_secret ?? throwErr("Client secret is missing"),
facebookConfigId: p.facebook_config_id,
microsoftTenantId: p.microsoft_tenant_id,
} as const))),
emailConfig: data.config.email_config.type === 'shared' ? {
type: 'shared'
@ -2537,6 +2538,7 @@ function adminProjectUpdateOptionsToCrud(options: AdminProjectUpdateOptions): Pr
client_id: p.clientId,
client_secret: p.clientSecret,
facebook_config_id: p.facebookConfigId,
microsoft_tenant_id: p.microsoftTenantId,
}),
})),
email_config: options.config?.emailConfig && (
@ -2633,6 +2635,7 @@ export type AdminOAuthProviderConfig = {
clientId: string,
clientSecret: string,
facebookConfigId?: string,
microsoftTenantId?: string,
}
) & OAuthProviderConfig;