Skip to content

Commit ae4f73b

Browse files
committed
v_deeplink
1 parent b5824bc commit ae4f73b

File tree

5 files changed

+50
-12
lines changed

5 files changed

+50
-12
lines changed

app/login/vercel/actions.ts

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,34 @@
22

33
import { cookies as getCookies, headers as getHeaders } from "next/headers";
44
import { redirect } from "next/navigation";
5-
import { createAuthorizationUrl } from "./issuer";
5+
import { createAuthorizationUrl, OIDC_ISSUER } from "./issuer";
6+
7+
export async function maybeStartAuthorizationAuto(
8+
params: Record<string, string>
9+
) {
10+
// See https://openid.net/specs/openid-connect-core-1_0.html#ThirdPartyInitiatedLogin
11+
const { iss, login_hint, target_link_uri, v_deeplink } = params;
12+
if (iss !== OIDC_ISSUER || !login_hint) {
13+
return;
14+
}
15+
16+
const headers = getHeaders();
17+
const cookies = getCookies();
18+
19+
const host = headers.get("host");
20+
21+
const protocol = host?.startsWith("localhost") ? "http" : "https";
22+
const callbackUrl = `${protocol}://${host}/login/vercel/callback`;
23+
24+
const { redirectTo, state } = await createAuthorizationUrl({
25+
callbackUrl,
26+
login_hint,
27+
v_deeplink,
28+
});
29+
30+
cookies.set("vercel-oidc-state", state, { httpOnly: true });
31+
return redirect(redirectTo);
32+
}
633

734
export async function startAuthorization(formData: FormData) {
835
console.log("startAuthorization:", Object.fromEntries(formData));

app/login/vercel/callback/route.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ import { getTokens } from "../issuer";
44
export async function GET(req: Request) {
55
const url = req.url;
66

7+
const params = Object.fromEntries(new URL(url).searchParams);
8+
const { v_deeplink } = params;
9+
710
const cookies = await getCookies();
811
const expectedState = cookies.get("vercel-oidc-state")?.value || undefined;
912
console.log("Callback:", { url, expectedState });
@@ -14,6 +17,6 @@ export async function GET(req: Request) {
1417
cookies.set("id-token", id_token);
1518
}
1619

17-
// TODO: redirect to the /dashboard
18-
return Response.json({ id_token, claims });
20+
// TODO: redirect to the /dashboard based on v_deeplink.
21+
return Response.json({ id_token, claims, v_deeplink });
1922
}

app/login/vercel/issuer.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import {
1111
} from "openid-client";
1212
import { createRemoteJWKSet, jwtVerify } from "jose";
1313

14-
const OIDC_ISSUER = "http://localhost:4000";
14+
export const OIDC_ISSUER = "http://localhost:4000";
1515
const OIDC_CLIENT_ID = "my_web_app1";
1616
const OIDC_CLIENT_SECRET = "super_secret_client_secret1";
1717

@@ -53,9 +53,13 @@ export async function getOidcConfiguration(): Promise<Configuration> {
5353

5454
export async function createAuthorizationUrl({
5555
callbackUrl,
56+
login_hint,
57+
v_deeplink,
5658
explicit = true,
5759
}: {
5860
callbackUrl: string;
61+
login_hint?: string;
62+
v_deeplink?: string;
5963
explicit?: boolean;
6064
}): Promise<{
6165
redirectTo: string;
@@ -70,6 +74,8 @@ export async function createAuthorizationUrl({
7074
scope: "openid",
7175
state,
7276
response_type: explicit ? "code" : "id_token",
77+
...(login_hint ? { login_hint } : null),
78+
...(v_deeplink ? { v_deeplink } : null),
7379
});
7480

7581
return {

app/login/vercel/page.tsx renamed to app/login/vercel/prompt/page.tsx

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,6 @@
1-
import { startAuthorization, startImplicitAuthorization } from "./actions";
2-
3-
interface LoginSearchParams {}
4-
5-
export default async function LoginVercelPage(props: {
6-
searchParams: Promise<LoginSearchParams>;
7-
}) {
8-
const searchParams = await props.searchParams;
1+
import { startAuthorization, startImplicitAuthorization } from "../actions";
92

3+
export default async function LoginVercelPage() {
104
return (
115
<div className="bg-gray-100 h-screen flex items-center justify-center">
126
<div className="bg-white shadow-md rounded px-8 pt-6 pb-8 mb-4 w-full max-w-sm">

app/login/vercel/route.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { maybeStartAuthorizationAuto } from "./actions";
2+
3+
export async function GET(req: Request) {
4+
const params = Object.fromEntries(new URL(req.url).searchParams);
5+
await maybeStartAuthorizationAuto(params);
6+
7+
return Response.redirect(new URL("/login/vercel/prompt", req.url), 307);
8+
}

0 commit comments

Comments
 (0)