diff --git a/components/Auth/OpenID.vue b/components/Auth/OpenID.vue
index 926e110..5783816 100644
--- a/components/Auth/OpenID.vue
+++ b/components/Auth/OpenID.vue
@@ -1,10 +1,14 @@
+
+
diff --git a/server/internal/oidc/index.ts b/server/internal/oidc/index.ts
index 24c4e33..ec5f43e 100644
--- a/server/internal/oidc/index.ts
+++ b/server/internal/oidc/index.ts
@@ -1,5 +1,6 @@
import { randomUUID } from "crypto";
import prisma from "../db/database";
+import type { User } from "~/prisma/client";
import { AuthMec } from "~/prisma/client";
import objectHandler from "../objects";
import type { Readable } from "stream";
@@ -12,10 +13,15 @@ interface OIDCWellKnown {
scopes_supported: string[];
}
+interface OIDCAuthSessionOptions {
+ redirect: string | undefined;
+}
+
interface OIDCAuthSession {
redirectUrl: string;
callbackUrl: string;
state: string;
+ options: OIDCAuthSessionOptions;
}
interface OIDCUserInfo {
@@ -132,7 +138,7 @@ export class OIDCManager {
};
}
- generateAuthSession(): OIDCAuthSession {
+ generateAuthSession(options?: OIDCAuthSessionOptions): OIDCAuthSession {
const stateKey = randomUUID();
const normalisedUrl = new URL(
@@ -148,12 +154,16 @@ export class OIDCManager {
redirectUrl: finalUrl,
callbackUrl: redirectUrl,
state: stateKey,
+ options: options ?? { redirect: undefined },
};
this.signinStateTable[stateKey] = session;
return session;
}
- async authorize(code: string, state: string) {
+ async authorize(
+ code: string,
+ state: string,
+ ): Promise<{ user: User; options: OIDCAuthSessionOptions } | string> {
const session = this.signinStateTable[state];
if (!session) return "Invalid state parameter";
@@ -191,7 +201,9 @@ export class OIDCManager {
const user = await this.fetchOrCreateUser(userinfo);
- return user;
+ if (typeof user === "string") return user;
+
+ return { user, options: session.options };
} catch (e) {
console.error(e);
return `Request to identity provider failed: ${e}`;
diff --git a/server/routes/auth/callback/oidc.get.ts b/server/routes/auth/callback/oidc.get.ts
index e2a6854..0bedf34 100644
--- a/server/routes/auth/callback/oidc.get.ts
+++ b/server/routes/auth/callback/oidc.get.ts
@@ -21,15 +21,19 @@ export default defineEventHandler(async (h3) => {
statusMessage: "No state in query params.",
});
- const user = await manager.authorize(code, state);
+ const result = await manager.authorize(code, state);
- if (typeof user === "string")
+ if (typeof result === "string")
throw createError({
statusCode: 403,
- statusMessage: `Failed to sign in: "${user}". Please try again.`,
+ statusMessage: `Failed to sign in: "${result}". Please try again.`,
});
- await sessionHandler.signin(h3, user.id, true);
+ await sessionHandler.signin(h3, result.user.id, true);
+
+ if (result.options.redirect) {
+ return sendRedirect(h3, result.options.redirect);
+ }
return sendRedirect(h3, "/");
});
diff --git a/server/routes/auth/oidc.get.ts b/server/routes/auth/oidc.get.ts
index be3cf94..a2b89e9 100644
--- a/server/routes/auth/oidc.get.ts
+++ b/server/routes/auth/oidc.get.ts
@@ -1,10 +1,16 @@
import { enabledAuthManagers } from "~/server/plugins/04.auth-init";
export default defineEventHandler((h3) => {
- if (!enabledAuthManagers.OpenID) return sendRedirect(h3, "/auth/signin");
+ const redirect = getQuery(h3).redirect?.toString();
+
+ if (!enabledAuthManagers.OpenID)
+ return sendRedirect(
+ h3,
+ `/auth/signin${redirect ? `?redirect=${encodeURIComponent(redirect)}` : ""}`,
+ );
const manager = enabledAuthManagers.OpenID;
- const { redirectUrl } = manager.generateAuthSession();
+ const { redirectUrl } = manager.generateAuthSession({ redirect });
return sendRedirect(h3, redirectUrl);
});