Skip to content

Commit

Permalink
feat: ✨ (website/auth/challenge) session がない場合は再ログインを要求するように修正
Browse files Browse the repository at this point in the history
  • Loading branch information
dino3616 committed Jan 24, 2024
1 parent cbb1a24 commit a82de4c
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 26 deletions.
13 changes: 7 additions & 6 deletions apps/website/src/app/auth/challenge/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,12 @@ export const GET = async (request: NextRequest) => {
const cookieStore = cookies();

const requestUrl = new URL(request.url);
const redirectUrl = requestUrl.pathname !== '/auth/challenge' ? requestUrl : getBaseUrl({ app: 'website' });

const lockerId = requestUrl.searchParams.get('lockerId');
const hashedFingerprintId = requestUrl.searchParams.get('hashedFingerprintId');
if (!lockerId || !hashedFingerprintId) {
return NextResponse.redirect(requestUrl);
return NextResponse.redirect(redirectUrl);
}

const supabase = createRouteHandlerClient({ cookies: () => cookieStore });
Expand All @@ -22,21 +23,21 @@ export const GET = async (request: NextRequest) => {
error,
} = await supabase.auth.getUser();
if (error) {
return NextResponse.redirect(requestUrl);
return NextResponse.redirect(`${getBaseUrl({ app: 'website' })}?asAuth=true&redirectPathname=${encodeURIComponent(redirectUrl.pathname)}`);
}

if (!user) {
return NextResponse.redirect(`${getBaseUrl({ app: 'website' })}?asAuth=true`);
return NextResponse.redirect(`${getBaseUrl({ app: 'website' })}?asAuth=true&redirectPathname=${encodeURIComponent(redirectUrl.pathname)}`);
}

const relatedUser = await relateFingerprintWithUserUseCase(user.id, hashedFingerprintId).catch(() => null);
if (!relatedUser) {
return NextResponse.redirect(requestUrl);
return NextResponse.redirect(redirectUrl);
}

if ((await clearLockerChallengeUseCase(lockerId).catch(() => null)) === null) {
return NextResponse.redirect(requestUrl);
return NextResponse.redirect(redirectUrl);
}

return NextResponse.redirect(`${getBaseUrl({ app: 'website' })}`);
return NextResponse.redirect(`${getBaseUrl({ app: 'website' })}?asRelateResult=true`);
};
3 changes: 2 additions & 1 deletion apps/website/src/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@ type RootPageProps = {
searchParams: {
asAuth?: boolean;
redirectPathname?: string;
asRelateResult?: boolean;
};
};

const RootPage: NextPage<RootPageProps> = ({ searchParams }) => (
<>
<script type="application/ld+json" dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }} />
<HeroSection asAuth={searchParams.asAuth} redirectPathname={searchParams.redirectPathname} />
<HeroSection asAuth={searchParams.asAuth} redirectPathname={searchParams.redirectPathname} asRelateResult={searchParams.asRelateResult} />
</>
);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { RelateResultDialog } from './relate-result-dialog.presenter';
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
'use client';

import { Dialog, DialogContent } from '@lockerai/core/component/dialog';
import type { ComponentPropsWithoutRef, ReactNode } from 'react';

type RelateResultDialogProps = Omit<ComponentPropsWithoutRef<typeof Dialog>, 'children' | 'className'>;

export const RelateResultDialog = ({ defaultOpen, ...props }: RelateResultDialogProps): ReactNode => (
<Dialog {...props}>
<DialogContent>
<p className="mt-8 flex items-center gap-3 text-center text-4xl font-bold text-sage-12">Linking fingerprint successful!</p>
<p className="text-xl text-sage-11">
Now your fingerprint is linked to your account.
<br />
Please scan your fingerprint again to unlock the door.
</p>
</DialogContent>
</Dialog>
);
Original file line number Diff line number Diff line change
Expand Up @@ -4,30 +4,17 @@ import { BrandIcon } from '@lockerai/core/component/brand-icon';
import { Button } from '@lockerai/core/component/button';
import { Dialog, DialogContent } from '@lockerai/core/component/dialog';
import { GoogleIcon } from '@lockerai/core/icon/google-icon';
import { useRouter } from 'next/navigation';
import { type ComponentPropsWithoutRef, type ReactNode, useEffect, useState } from 'react';
import { type ComponentPropsWithoutRef, type ReactNode, useState } from 'react';

type SignInDialogProps = Omit<ComponentPropsWithoutRef<typeof Dialog>, 'children' | 'className'> & {
signIn: () => Promise<void>;
};

export const SignInDialog = ({ signIn, defaultOpen, ...props }: SignInDialogProps): ReactNode => {
const [open, setOpen] = useState<boolean>();
export const SignInDialog = ({ signIn, onOpenChange, ...props }: SignInDialogProps): ReactNode => {
const [loading, setLoading] = useState(false);
const router = useRouter();

useEffect(() => {
setOpen(defaultOpen ?? false);
}, [defaultOpen]);

useEffect(() => {
if (open === false) {
router.push('/');
}
}, [open, router]);

return (
<Dialog open={open} onOpenChange={setOpen} {...props}>
<Dialog onOpenChange={onOpenChange} {...props}>
<DialogContent>
<div className="flex items-center gap-2">
<BrandIcon className="h-16" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,39 @@
import { BrandLogo } from '@lockerai/core/component/brand-logo';
import { LinkButton } from '@lockerai/core/component/link-button';
import { motion } from 'framer-motion';
import { type ComponentPropsWithoutRef, type ReactNode, useState } from 'react';
import { useRouter } from 'next/navigation';
import { type ComponentPropsWithoutRef, type ReactNode, useEffect, useState } from 'react';
import { RelateResultDialog } from './component/relate-result-dialog';
import { SignInDialog } from './component/sign-in-dialog';

type HeroSectionProps = Omit<ComponentPropsWithoutRef<'section'>, 'children' | 'className'> & {
asAuth?: boolean;
redirectPathname?: string;
asRelateResult?: boolean;
};

export const HeroSection = ({ asAuth, redirectPathname, ...props }: HeroSectionProps): ReactNode => {
export const HeroSection = ({ asAuth, redirectPathname, asRelateResult, ...props }: HeroSectionProps): ReactNode => {
const [isLogoAnimated, setIsLogoAnimated] = useState(false);
const [isSignInDialogOpen, setIsSignInDialogOpen] = useState<boolean>();
const [isRelateResultDialogOpen, setIsRelateResultDialogOpen] = useState<boolean>();

const router = useRouter();

useEffect(() => {
setIsSignInDialogOpen(asAuth ?? false);
setIsRelateResultDialogOpen(asRelateResult ?? false);
}, [asAuth, asRelateResult]);

useEffect(() => {
if (isSignInDialogOpen === false && isRelateResultDialogOpen === false) {
router.push('/');
}
}, [isSignInDialogOpen, isRelateResultDialogOpen, router]);

return (
<section className="relative flex h-[100svh] items-center justify-center px-5 tablet:px-20" {...props}>
<SignInDialog defaultOpen={asAuth} redirectPathname={redirectPathname} />
<SignInDialog open={isSignInDialogOpen} onOpenChange={setIsSignInDialogOpen} redirectPathname={redirectPathname} />
<RelateResultDialog open={isRelateResultDialogOpen} onOpenChange={setIsRelateResultDialogOpen} defaultOpen={asRelateResult} />
<div className="flex w-[940px] flex-col items-center gap-8 tablet:gap-16">
<motion.hgroup layout data-chromatic="ignore" className="flex flex-col items-center gap-6">
<motion.h1 layout className="w-fit">
Expand Down

0 comments on commit a82de4c

Please sign in to comment.