mirror of
https://github.com/fosrl/pangolin.git
synced 2026-02-07 21:46:38 +00:00
prefill username in login
This commit is contained in:
@@ -7,22 +7,35 @@ import { cache } from "react";
|
|||||||
export const dynamic = "force-dynamic";
|
export const dynamic = "force-dynamic";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
searchParams: Promise<{ code?: string }>;
|
searchParams: Promise<{ code?: string; user?: string }>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function deviceRedirectSearchParams(params: {
|
||||||
|
code?: string;
|
||||||
|
user?: string;
|
||||||
|
}): string {
|
||||||
|
const search = new URLSearchParams();
|
||||||
|
if (params.code) search.set("code", params.code);
|
||||||
|
if (params.user) search.set("user", params.user);
|
||||||
|
const q = search.toString();
|
||||||
|
return q ? `?${q}` : "";
|
||||||
|
}
|
||||||
|
|
||||||
export default async function DeviceLoginPage({ searchParams }: Props) {
|
export default async function DeviceLoginPage({ searchParams }: Props) {
|
||||||
const user = await verifySession({ forceLogin: true });
|
const user = await verifySession({ forceLogin: true });
|
||||||
|
|
||||||
const params = await searchParams;
|
const params = await searchParams;
|
||||||
const code = params.code || "";
|
const code = params.code || "";
|
||||||
|
const defaultUser = params.user;
|
||||||
|
|
||||||
if (!user) {
|
if (!user) {
|
||||||
const redirectDestination = code
|
const redirectDestination = `/auth/login/device${deviceRedirectSearchParams({ code, user: params.user })}`;
|
||||||
? `/auth/login/device?code=${encodeURIComponent(code)}`
|
const loginUrl = new URL("/auth/login", "http://x");
|
||||||
: "/auth/login/device";
|
loginUrl.searchParams.set("forceLogin", "true");
|
||||||
redirect(
|
loginUrl.searchParams.set("redirect", redirectDestination);
|
||||||
`/auth/login?forceLogin=true&redirect=${encodeURIComponent(redirectDestination)}`
|
if (defaultUser) loginUrl.searchParams.set("user", defaultUser);
|
||||||
);
|
console.log("loginUrl", loginUrl.pathname + loginUrl.search);
|
||||||
|
redirect(loginUrl.pathname + loginUrl.search);
|
||||||
}
|
}
|
||||||
|
|
||||||
const userName = user
|
const userName = user
|
||||||
@@ -37,6 +50,7 @@ export default async function DeviceLoginPage({ searchParams }: Props) {
|
|||||||
userEmail={user?.email || ""}
|
userEmail={user?.email || ""}
|
||||||
userName={userName}
|
userName={userName}
|
||||||
initialCode={code}
|
initialCode={code}
|
||||||
|
userQueryParam={defaultUser}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -72,6 +72,8 @@ export default async function Page(props: {
|
|||||||
searchParams.redirect = redirectUrl;
|
searchParams.redirect = redirectUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const defaultUser = searchParams.user as string | undefined;
|
||||||
|
|
||||||
// Only use SmartLoginForm if NOT (OSS build OR org-only IdP enabled)
|
// Only use SmartLoginForm if NOT (OSS build OR org-only IdP enabled)
|
||||||
const useSmartLogin =
|
const useSmartLogin =
|
||||||
build === "saas" || (build === "enterprise" && env.flags.useOrgOnlyIdp);
|
build === "saas" || (build === "enterprise" && env.flags.useOrgOnlyIdp);
|
||||||
@@ -151,6 +153,7 @@ export default async function Page(props: {
|
|||||||
<SmartLoginForm
|
<SmartLoginForm
|
||||||
redirect={redirectUrl}
|
redirect={redirectUrl}
|
||||||
forceLogin={forceLogin}
|
forceLogin={forceLogin}
|
||||||
|
defaultUser={defaultUser}
|
||||||
/>
|
/>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
@@ -165,6 +168,7 @@ export default async function Page(props: {
|
|||||||
(build === "saas" || env.flags.useOrgOnlyIdp)
|
(build === "saas" || env.flags.useOrgOnlyIdp)
|
||||||
}
|
}
|
||||||
searchParams={searchParams}
|
searchParams={searchParams}
|
||||||
|
defaultUser={defaultUser}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ type DashboardLoginFormProps = {
|
|||||||
searchParams?: {
|
searchParams?: {
|
||||||
[key: string]: string | string[] | undefined;
|
[key: string]: string | string[] | undefined;
|
||||||
};
|
};
|
||||||
|
defaultUser?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function DashboardLoginForm({
|
export default function DashboardLoginForm({
|
||||||
@@ -36,7 +37,8 @@ export default function DashboardLoginForm({
|
|||||||
idps,
|
idps,
|
||||||
forceLogin,
|
forceLogin,
|
||||||
showOrgLogin,
|
showOrgLogin,
|
||||||
searchParams
|
searchParams,
|
||||||
|
defaultUser
|
||||||
}: DashboardLoginFormProps) {
|
}: DashboardLoginFormProps) {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { env } = useEnvContext();
|
const { env } = useEnvContext();
|
||||||
@@ -75,6 +77,7 @@ export default function DashboardLoginForm({
|
|||||||
redirect={redirect}
|
redirect={redirect}
|
||||||
idps={idps}
|
idps={idps}
|
||||||
forceLogin={forceLogin}
|
forceLogin={forceLogin}
|
||||||
|
defaultEmail={defaultUser}
|
||||||
onLogin={(redirectUrl) => {
|
onLogin={(redirectUrl) => {
|
||||||
if (redirectUrl) {
|
if (redirectUrl) {
|
||||||
const safe = cleanRedirect(redirectUrl);
|
const safe = cleanRedirect(redirectUrl);
|
||||||
|
|||||||
@@ -55,12 +55,14 @@ type DeviceLoginFormProps = {
|
|||||||
userEmail: string;
|
userEmail: string;
|
||||||
userName?: string;
|
userName?: string;
|
||||||
initialCode?: string;
|
initialCode?: string;
|
||||||
|
userQueryParam?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function DeviceLoginForm({
|
export default function DeviceLoginForm({
|
||||||
userEmail,
|
userEmail,
|
||||||
userName,
|
userName,
|
||||||
initialCode = ""
|
initialCode = "",
|
||||||
|
userQueryParam
|
||||||
}: DeviceLoginFormProps) {
|
}: DeviceLoginFormProps) {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { env } = useEnvContext();
|
const { env } = useEnvContext();
|
||||||
@@ -219,9 +221,12 @@ export default function DeviceLoginForm({
|
|||||||
const currentSearch =
|
const currentSearch =
|
||||||
typeof window !== "undefined" ? window.location.search : "";
|
typeof window !== "undefined" ? window.location.search : "";
|
||||||
const redirectTarget = `/auth/login/device${currentSearch || ""}`;
|
const redirectTarget = `/auth/login/device${currentSearch || ""}`;
|
||||||
router.push(
|
const loginUrl = new URL("/auth/login", "http://x");
|
||||||
`/auth/login?forceLogin=true&redirect=${encodeURIComponent(redirectTarget)}`
|
loginUrl.searchParams.set("forceLogin", "true");
|
||||||
);
|
loginUrl.searchParams.set("redirect", redirectTarget);
|
||||||
|
if (userQueryParam)
|
||||||
|
loginUrl.searchParams.set("user", userQueryParam);
|
||||||
|
router.push(loginUrl.pathname + loginUrl.search);
|
||||||
router.refresh();
|
router.refresh();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ type LoginFormProps = {
|
|||||||
idps?: LoginFormIDP[];
|
idps?: LoginFormIDP[];
|
||||||
orgId?: string;
|
orgId?: string;
|
||||||
forceLogin?: boolean;
|
forceLogin?: boolean;
|
||||||
|
defaultEmail?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function LoginForm({
|
export default function LoginForm({
|
||||||
@@ -61,7 +62,8 @@ export default function LoginForm({
|
|||||||
onLogin,
|
onLogin,
|
||||||
idps,
|
idps,
|
||||||
orgId,
|
orgId,
|
||||||
forceLogin
|
forceLogin,
|
||||||
|
defaultEmail
|
||||||
}: LoginFormProps) {
|
}: LoginFormProps) {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
@@ -116,7 +118,7 @@ export default function LoginForm({
|
|||||||
const form = useForm({
|
const form = useForm({
|
||||||
resolver: zodResolver(formSchema),
|
resolver: zodResolver(formSchema),
|
||||||
defaultValues: {
|
defaultValues: {
|
||||||
email: "",
|
email: defaultEmail ?? "",
|
||||||
password: ""
|
password: ""
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { useState } from "react";
|
import { useEffect, useRef, useState } from "react";
|
||||||
import { useForm } from "react-hook-form";
|
import { useForm } from "react-hook-form";
|
||||||
import { zodResolver } from "@hookform/resolvers/zod";
|
import { zodResolver } from "@hookform/resolvers/zod";
|
||||||
import * as z from "zod";
|
import * as z from "zod";
|
||||||
@@ -42,6 +42,7 @@ const isValidEmail = (str: string): boolean => {
|
|||||||
type SmartLoginFormProps = {
|
type SmartLoginFormProps = {
|
||||||
redirect?: string;
|
redirect?: string;
|
||||||
forceLogin?: boolean;
|
forceLogin?: boolean;
|
||||||
|
defaultUser?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
type ViewState =
|
type ViewState =
|
||||||
@@ -59,7 +60,8 @@ type ViewState =
|
|||||||
|
|
||||||
export default function SmartLoginForm({
|
export default function SmartLoginForm({
|
||||||
redirect,
|
redirect,
|
||||||
forceLogin
|
forceLogin,
|
||||||
|
defaultUser
|
||||||
}: SmartLoginFormProps) {
|
}: SmartLoginFormProps) {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { lookup, loading, error } = useUserLookup();
|
const { lookup, loading, error } = useUserLookup();
|
||||||
@@ -72,10 +74,18 @@ export default function SmartLoginForm({
|
|||||||
const form = useForm<z.infer<typeof identifierSchema>>({
|
const form = useForm<z.infer<typeof identifierSchema>>({
|
||||||
resolver: zodResolver(identifierSchema),
|
resolver: zodResolver(identifierSchema),
|
||||||
defaultValues: {
|
defaultValues: {
|
||||||
identifier: ""
|
identifier: defaultUser ?? ""
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const hasAutoLookedUp = useRef(false);
|
||||||
|
useEffect(() => {
|
||||||
|
if (defaultUser?.trim() && !hasAutoLookedUp.current) {
|
||||||
|
hasAutoLookedUp.current = true;
|
||||||
|
void handleLookup({ identifier: defaultUser.trim() });
|
||||||
|
}
|
||||||
|
}, [defaultUser]);
|
||||||
|
|
||||||
const handleLookup = async (values: z.infer<typeof identifierSchema>) => {
|
const handleLookup = async (values: z.infer<typeof identifierSchema>) => {
|
||||||
const identifier = values.identifier.trim();
|
const identifier = values.identifier.trim();
|
||||||
const isEmail = isValidEmail(identifier);
|
const isEmail = isValidEmail(identifier);
|
||||||
|
|||||||
Reference in New Issue
Block a user