feat: finished oidc form functions

This commit is contained in:
Sheen Capadngan
2024-06-17 22:37:23 +08:00
parent 66e5edcfc0
commit 61fcb2b605
11 changed files with 580 additions and 24 deletions
+3 -1
View File
@@ -113,6 +113,9 @@ import {
TLdapGroupMaps,
TLdapGroupMapsInsert,
TLdapGroupMapsUpdate,
TOidcConfigs,
TOidcConfigsInsert,
TOidcConfigsUpdate,
TOrganizations,
TOrganizationsInsert,
TOrganizationsUpdate,
@@ -255,7 +258,6 @@ import {
TWebhooksInsert,
TWebhooksUpdate
} from "@app/db/schemas";
import { TOidcConfigs, TOidcConfigsInsert, TOidcConfigsUpdate } from "@app/db/schemas/oidc-configs";
declare module "knex/types/tables" {
interface Tables {
@@ -6,17 +6,17 @@ export async function up(knex: Knex): Promise<void> {
if (!(await knex.schema.hasTable(TableName.OidcConfig))) {
await knex.schema.createTable(TableName.OidcConfig, (tb) => {
tb.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid());
tb.string("issuer");
tb.string("authorizationEndpoint");
tb.string("jwksUri");
tb.string("tokenEndpoint");
tb.string("userinfoEndpoint");
tb.text("encryptedClientId");
tb.string("clientIdIV");
tb.string("clientIdTag");
tb.text("encryptedClientSecret");
tb.string("clientSecretIV");
tb.string("clientSecretTag");
tb.string("issuer").notNullable();
tb.string("authorizationEndpoint").notNullable();
tb.string("jwksUri").notNullable();
tb.string("tokenEndpoint").notNullable();
tb.string("userinfoEndpoint").notNullable();
tb.text("encryptedClientId").notNullable();
tb.string("clientIdIV").notNullable();
tb.string("clientIdTag").notNullable();
tb.text("encryptedClientSecret").notNullable();
tb.string("clientSecretIV").notNullable();
tb.string("clientSecretTag").notNullable();
tb.boolean("isActive").notNullable();
tb.timestamps(true, true, true);
tb.uuid("orgId").notNullable().unique();
+1
View File
@@ -36,6 +36,7 @@ export * from "./kms-root-config";
export * from "./ldap-configs";
export * from "./ldap-group-maps";
export * from "./models";
export * from "./oidc-configs";
export * from "./org-bots";
export * from "./org-memberships";
export * from "./org-roles";
+11 -11
View File
@@ -9,17 +9,17 @@ import { TImmutableDBKeys } from "./models";
export const OidcConfigsSchema = z.object({
id: z.string().uuid(),
issuer: z.string().nullable().optional(),
authorizationEndpoint: z.string().nullable().optional(),
jwksUri: z.string().nullable().optional(),
tokenEndpoint: z.string().nullable().optional(),
userinfoEndpoint: z.string().nullable().optional(),
encryptedClientId: z.string().nullable().optional(),
clientIdIV: z.string().nullable().optional(),
clientIdTag: z.string().nullable().optional(),
encryptedClientSecret: z.string().nullable().optional(),
clientSecretIV: z.string().nullable().optional(),
clientSecretTag: z.string().nullable().optional(),
issuer: z.string(),
authorizationEndpoint: z.string(),
jwksUri: z.string(),
tokenEndpoint: z.string(),
userinfoEndpoint: z.string(),
encryptedClientId: z.string(),
clientIdIV: z.string(),
clientIdTag: z.string(),
encryptedClientSecret: z.string(),
clientSecretIV: z.string(),
clientSecretTag: z.string(),
isActive: z.boolean(),
createdAt: z.date(),
updatedAt: z.date(),
+6 -1
View File
@@ -101,6 +101,7 @@ import { integrationAuthServiceFactory } from "@app/services/integration-auth/in
import { kmsDALFactory } from "@app/services/kms/kms-dal";
import { kmsRootConfigDALFactory } from "@app/services/kms/kms-root-config-dal";
import { kmsServiceFactory } from "@app/services/kms/kms-service";
import { oidcConfigDALFactory } from "@app/services/oidc/oidc-config-dal";
import { oidcConfigServiceFactory } from "@app/services/oidc/oidc-config-service";
import { incidentContactDALFactory } from "@app/services/org/incident-contacts-dal";
import { orgBotDALFactory } from "@app/services/org/org-bot-dal";
@@ -241,6 +242,7 @@ export const registerRoutes = async (
const ldapConfigDAL = ldapConfigDALFactory(db);
const ldapGroupMapDAL = ldapGroupMapDALFactory(db);
const oidcConfigDAL = oidcConfigDALFactory(db);
const accessApprovalPolicyDAL = accessApprovalPolicyDALFactory(db);
const accessApprovalRequestDAL = accessApprovalRequestDALFactory(db);
const accessApprovalPolicyApproverDAL = accessApprovalPolicyApproverDALFactory(db);
@@ -846,7 +848,10 @@ export const registerRoutes = async (
userAliasDAL,
licenseService,
tokenService,
smtpService
smtpService,
orgBotDAL,
permissionService,
oidcConfigDAL
});
await superAdminService.initServerCfg();
@@ -12,6 +12,9 @@ import { z } from "zod";
import { OidcConfigsSchema } from "@app/db/schemas/oidc-configs";
import { getConfig } from "@app/lib/config/env";
import { writeLimit } from "@app/server/config/rateLimiter";
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
import { AuthMode } from "@app/services/auth/auth-type";
export const registerOidcRouter = async (server: FastifyZodProvider) => {
const appCfg = getConfig();
@@ -101,6 +104,7 @@ export const registerOidcRouter = async (server: FastifyZodProvider) => {
jwksUri: true,
tokenEndpoint: true,
userinfoEndpoint: true,
isActive: true,
orgId: true
}).extend({
clientId: z.string(),
@@ -122,4 +126,95 @@ export const registerOidcRouter = async (server: FastifyZodProvider) => {
return oidc;
}
});
server.route({
method: "PATCH",
url: "/config",
config: {
rateLimit: writeLimit
},
onRequest: verifyAuth([AuthMode.JWT]),
schema: {
body: z
.object({
issuer: z.string(),
authorizationEndpoint: z.string(),
jwksUri: z.string(),
tokenEndpoint: z.string(),
userinfoEndpoint: z.string(),
clientId: z.string(),
clientSecret: z.string(),
isActive: z.boolean()
})
.partial()
.merge(z.object({ orgSlug: z.string() })),
response: {
200: OidcConfigsSchema.pick({
id: true,
issuer: true,
authorizationEndpoint: true,
jwksUri: true,
tokenEndpoint: true,
userinfoEndpoint: true,
orgId: true,
isActive: true
})
}
},
handler: async (req) => {
const oidc = await server.services.oidc.updateOidcCfg({
actor: req.permission.type,
actorId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId,
...req.body
});
return oidc;
}
});
server.route({
method: "POST",
url: "/config",
config: {
rateLimit: writeLimit
},
onRequest: verifyAuth([AuthMode.JWT]),
schema: {
body: z.object({
issuer: z.string(),
authorizationEndpoint: z.string(),
jwksUri: z.string(),
tokenEndpoint: z.string(),
userinfoEndpoint: z.string(),
clientId: z.string(),
clientSecret: z.string(),
isActive: z.boolean(),
orgSlug: z.string()
}),
response: {
200: OidcConfigsSchema.pick({
id: true,
issuer: true,
authorizationEndpoint: true,
jwksUri: true,
tokenEndpoint: true,
userinfoEndpoint: true,
orgId: true,
isActive: true
})
}
},
handler: async (req) => {
const oidc = await server.services.oidc.createOidcCfg({
actor: req.permission.type,
actorId: req.permission.id,
actorAuthMethod: req.permission.authMethod,
actorOrgId: req.permission.orgId,
...req.body
});
return oidc;
}
});
};
@@ -13,6 +13,18 @@ export type TGetOidcCfgDTO = {
orgSlug: string;
} & TGenericPermission;
export type TCreateOidcCfgDTO = {
issuer: string;
authorizationEndpoint: string;
jwksUri: string;
tokenEndpoint: string;
userinfoEndpoint: string;
clientId: string;
clientSecret: string;
isActive: boolean;
orgSlug: string;
} & TGenericPermission;
export type TUpdateOidcCfgDTO = Partial<{
issuer: string;
authorizationEndpoint: string;