set mfa page, auth service

This commit is contained in:
peintnermax
2024-04-15 17:23:28 +02:00
parent 437ba4375f
commit cee9c272be
6 changed files with 86 additions and 26 deletions

View File

@@ -1,35 +1,44 @@
import { getBrandingSettings, getLoginSettings, server } from "#/lib/zitadel";
import {
addMyAuthFactorOTP,
getBrandingSettings,
getLoginSettings,
getSession,
server,
} from "#/lib/zitadel";
import DynamicTheme from "#/ui/DynamicTheme";
import TOTPForm from "#/ui/TOTPForm";
import TOTPRegister from "#/ui/TOTPRegister";
import { getMostRecentCookieWithLoginname } from "#/utils/cookies";
export default async function Page({
searchParams,
}: {
searchParams: Record<string | number | symbol, string | undefined>;
}) {
const { loginName, authRequestId, sessionId, organization, code, submit } =
searchParams;
const { loginName, organization } = searchParams;
const branding = await getBrandingSettings(server, organization);
const loginSettings = await getLoginSettings(server, organization);
const auth = await getMostRecentCookieWithLoginname(
loginName,
organization
).then((cookie) => {
if (cookie) {
return addMyAuthFactorOTP(cookie.token);
} else {
throw new Error("No cookie found");
}
});
return (
<DynamicTheme branding={branding}>
<div className="flex flex-col items-center space-y-4">
<h1>Verify 2-Factor</h1>
<p className="ztdl-p">Enter the code from your authenticator app. </p>
<h1>Register TOTP</h1>
<p className="ztdl-p">
Scan the QR Code or navigate to the URL manually.
</p>
<div>
{loginSettings?.secondFactors.map((factor) => {
return (
<div>
{factor === 1 && <div>TOTP</div>}
{factor === 2 && <div>U2F</div>}
{factor === 3 && <div>OTP Email</div>}
{factor === 4 && <div>OTP Sms</div>}
</div>
);
})}
{auth && <div>{auth.url}</div>}
<TOTPRegister></TOTPRegister>
</div>
</div>
</DynamicTheme>

View File

@@ -2,17 +2,20 @@ import {
LegalAndSupportSettings,
PasswordComplexitySettings,
ZitadelServer,
VerifyMyAuthFactorOTPResponse,
ZitadelServerOptions,
user,
oidc,
settings,
getServers,
auth,
initializeServer,
session,
GetGeneralSettingsResponse,
CreateSessionResponse,
GetBrandingSettingsResponse,
GetPasswordComplexitySettingsResponse,
AddMyAuthFactorOTPResponse,
GetLegalAndSupportSettingsResponse,
AddHumanUserResponse,
BrandingSettings,
@@ -80,6 +83,28 @@ export async function getLoginSettings(
.then((resp: GetLoginSettingsResponse) => resp.settings);
}
export async function verifyMyAuthFactorOTP(
code: string
): Promise<VerifyMyAuthFactorOTPResponse> {
const authService = auth.getAuth(server);
return authService.verifyMyAuthFactorOTP({ code }, {});
}
export async function addMyAuthFactorOTP(
token: string
): Promise<AddMyAuthFactorOTPResponse> {
const zitadelConfig: ZitadelServerOptions = {
name: "zitadel login",
apiUrl: process.env.ZITADEL_API_URL ?? "",
token: token,
};
const server: ZitadelServer = initializeServer(zitadelConfig);
const authService = auth.getAuth(server);
return authService.addMyAuthFactorOTP({}, {});
}
export async function getGeneralSettings(
server: ZitadelServer
): Promise<string[] | undefined> {

View File

@@ -0,0 +1,3 @@
export default function TOTPRegister() {
return <div></div>;
}

View File

@@ -5,25 +5,43 @@ import {
AuthServiceDefinition,
GetMyUserResponse,
} from "../proto/server/zitadel/auth";
import { ZitadelServer } from "../server";
import { ZitadelServer, getServers } from "../server";
import { authMiddleware } from "../middleware";
const createClient = <Client>(
definition: CompatServiceDefinition,
accessToken: string
apiUrl: string,
token: string
) => {
if (!apiUrl) {
throw Error("ZITADEL_API_URL not set");
}
const channel = createChannel(process.env.ZITADEL_API_URL ?? "");
return createClientFactory()
.use(authMiddleware(accessToken))
.use(authMiddleware(token))
.create(definition, channel) as Client;
};
export async function getAuth(app?: ZitadelServer): Promise<AuthServiceClient> {
export const getAuth = (app?: string | ZitadelServer) => {
let config;
if (app && typeof app === "string") {
const apps = getServers();
config = apps.find((a) => a.name === app)?.config;
} else if (app && typeof app === "object") {
config = app.config;
}
if (!config) {
throw Error("No ZITADEL app found");
}
return createClient<AuthServiceClient>(
AuthServiceDefinition as CompatServiceDefinition,
""
config.apiUrl,
config.token
);
}
};
export async function getMyUser(): Promise<GetMyUserResponse> {
const auth = await getAuth();

View File

@@ -1,2 +1,2 @@
export * from "../proto/server/zitadel/auth";
export { getAuth } from "./auth";
export * from "./auth";
export * as auth from "../proto/server/zitadel/auth";

View File

@@ -3,6 +3,7 @@ import * as session from "./v2/session";
import * as user from "./v2/user";
import * as oidc from "./v2/oidc";
import * as management from "./management";
import * as auth from "./auth";
import * as login from "./proto/server/zitadel/settings/v2beta/login_settings";
import * as password from "./proto/server/zitadel/settings/v2beta/password_settings";
@@ -96,7 +97,10 @@ export * from "./proto/server/zitadel/idp";
export { type LegalAndSupportSettings } from "./proto/server/zitadel/settings/v2beta/legal_settings";
export { type PasswordComplexitySettings } from "./proto/server/zitadel/settings/v2beta/password_settings";
export { type ResourceOwnerType } from "./proto/server/zitadel/settings/v2beta/settings";
export {
type VerifyMyAuthFactorOTPResponse,
AddMyAuthFactorOTPResponse,
} from "./proto/server/zitadel/auth";
import {
getServers,
initializeServer,
@@ -118,4 +122,5 @@ export {
password,
legal,
oidc,
auth,
};