initial commit
This commit is contained in:
120
convex/comdirect/auth.ts
Normal file
120
convex/comdirect/auth.ts
Normal file
@@ -0,0 +1,120 @@
|
||||
import { action } from "../_generated/server";
|
||||
import { v } from "convex/values";
|
||||
import { internal } from "../_generated/api";
|
||||
import { getAuthUserId } from "@convex-dev/auth/server";
|
||||
import {
|
||||
activateSession,
|
||||
getSecondaryToken,
|
||||
getSessions,
|
||||
oauthToken,
|
||||
validateSession,
|
||||
} from "./client";
|
||||
|
||||
function randomUuid(): string {
|
||||
return crypto.randomUUID();
|
||||
}
|
||||
|
||||
export const start = action({
|
||||
args: {
|
||||
zugangsnummer: v.string(),
|
||||
pin: v.string(),
|
||||
},
|
||||
returns: v.object({
|
||||
challengeType: v.string(),
|
||||
photoTanPngBase64: v.optional(v.string()),
|
||||
}),
|
||||
handler: async (ctx, args) => {
|
||||
const userId = await getAuthUserId(ctx);
|
||||
if (!userId) throw new Error("Nicht angemeldet");
|
||||
|
||||
const clientId = process.env.COMDIRECT_CLIENT_ID;
|
||||
const clientSecret = process.env.COMDIRECT_CLIENT_SECRET;
|
||||
if (!clientId || !clientSecret) {
|
||||
throw new Error("comdirect API-Zugangsdaten nicht konfiguriert");
|
||||
}
|
||||
|
||||
const sessionUuid = randomUuid();
|
||||
const tokenResponse = await oauthToken(
|
||||
{
|
||||
grant_type: "password",
|
||||
username: args.zugangsnummer,
|
||||
password: args.pin,
|
||||
},
|
||||
clientId,
|
||||
clientSecret,
|
||||
);
|
||||
|
||||
const sessions = await getSessions(tokenResponse.access_token, sessionUuid);
|
||||
const session = sessions[0];
|
||||
if (!session) throw new Error("Keine comdirect-Session gefunden");
|
||||
|
||||
const challenge = await validateSession(
|
||||
tokenResponse.access_token,
|
||||
sessionUuid,
|
||||
session.identifier,
|
||||
);
|
||||
|
||||
await ctx.runMutation(internal.comdirect.internal.upsertSession, {
|
||||
userId,
|
||||
sessionUuid,
|
||||
identifier: session.identifier,
|
||||
accessToken: tokenResponse.access_token,
|
||||
refreshToken: tokenResponse.refresh_token,
|
||||
secondaryActive: false,
|
||||
challengeId: challenge.challengeId,
|
||||
challengeType: challenge.challengeType,
|
||||
status: "challenged",
|
||||
expiresAt: Date.now() + tokenResponse.expires_in * 1000,
|
||||
});
|
||||
|
||||
return {
|
||||
challengeType: challenge.challengeType,
|
||||
photoTanPngBase64:
|
||||
challenge.challengeType === "P_TAN" ? challenge.challenge : undefined,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
export const confirm = action({
|
||||
args: { tan: v.optional(v.string()) },
|
||||
returns: v.object({ success: v.boolean() }),
|
||||
handler: async (ctx, args) => {
|
||||
const userId = await getAuthUserId(ctx);
|
||||
if (!userId) throw new Error("Nicht angemeldet");
|
||||
|
||||
const clientId = process.env.COMDIRECT_CLIENT_ID;
|
||||
const clientSecret = process.env.COMDIRECT_CLIENT_SECRET;
|
||||
if (!clientId || !clientSecret) {
|
||||
throw new Error("comdirect API-Zugangsdaten nicht konfiguriert");
|
||||
}
|
||||
|
||||
const session = await ctx.runQuery(internal.comdirect.internal.getSession, { userId });
|
||||
if (!session?.accessToken || !session.identifier || !session.challengeId) {
|
||||
throw new Error("Keine aktive comdirect-Session");
|
||||
}
|
||||
|
||||
await activateSession(
|
||||
session.accessToken,
|
||||
session.sessionUuid,
|
||||
session.identifier,
|
||||
session.challengeId,
|
||||
args.tan,
|
||||
);
|
||||
|
||||
const secondary = await getSecondaryToken(session.accessToken, clientId, clientSecret);
|
||||
|
||||
await ctx.runMutation(internal.comdirect.internal.upsertSession, {
|
||||
userId,
|
||||
sessionUuid: session.sessionUuid,
|
||||
identifier: session.identifier,
|
||||
accessToken: secondary.access_token,
|
||||
refreshToken: secondary.refresh_token,
|
||||
secondaryActive: true,
|
||||
challengeId: session.challengeId,
|
||||
challengeType: session.challengeType,
|
||||
status: "active",
|
||||
});
|
||||
|
||||
return { success: true };
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user