Skip to content

Commit

Permalink
Mfa
Browse files Browse the repository at this point in the history
  • Loading branch information
pontusab committed Dec 8, 2023
1 parent bfc39db commit 5d721d7
Show file tree
Hide file tree
Showing 7 changed files with 78 additions and 26 deletions.
23 changes: 23 additions & 0 deletions apps/dashboard/src/actions/mfa-verify-action.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
"use server";

import { createClient } from "@midday/supabase/server";
import { revalidatePath } from "next/cache";
import { action } from "./safe-action";
import { mfaVerifySchema } from "./schema";

export const mfaVerifyAction = action(
mfaVerifySchema,
async ({ factorId, challengeId, code }) => {
const supabase = createClient();

const { data } = await supabase.auth.mfa.verify({
factorId,
challengeId,
code,
});

revalidatePath("/settings/security");

return data;
}
);
8 changes: 7 additions & 1 deletion apps/dashboard/src/actions/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,13 @@ export const createFolderSchema = z.object({
});

export const unenrollMfaSchema = z.object({
factoryId: z.string(),
factorId: z.string(),
});

export const mfaVerifySchema = z.object({
factorId: z.string(),
challengeId: z.string(),
code: z.string(),
});

export const shareFileSchema = z.object({
Expand Down
4 changes: 2 additions & 2 deletions apps/dashboard/src/actions/unenroll-mfa-action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ import { unenrollMfaSchema } from "./schema";

export const unenrollMfaAction = action(
unenrollMfaSchema,
async ({ factoryId }) => {
async ({ factorId }) => {
const supabase = createClient();

const { data, error } = await supabase.auth.mfa.unenroll({
factoryId,
factorId,
});

if (error) {
Expand Down
18 changes: 15 additions & 3 deletions apps/dashboard/src/components/enroll-mfa.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { createClient } from "@midday/supabase/client";
import { Button } from "@midday/ui/button";
import Image from "next/image";
import Link from "next/link";
import { useRouter } from "next/navigation";
import { useEffect, useState } from "react";
import PinField from "react-pin-field";
Expand Down Expand Up @@ -48,6 +48,14 @@ export function EnrollMFA() {
enroll();
}, []);

const handleOnCancel = () => {
supabase.auth.mfa.unenroll({
factorId,
});

router.push("/onboarding");
};

return (
<>
<div className="flex items-center justify-center">
Expand Down Expand Up @@ -75,9 +83,13 @@ export function EnrollMFA() {
</div>

<div className="flex border-t-[1px] pt-4 mt-6 justify-center mb-6">
<Link href="/onboarding" className="text-medium text-sm">
<Button
onClick={handleOnCancel}
variant="ghost"
className="text-medium text-sm hover:bg-transparent"
>
Cancel
</Link>
</Button>
</div>
</>
);
Expand Down
2 changes: 1 addition & 1 deletion apps/dashboard/src/components/mfa-list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export async function MFAList() {
</p>
</div>

<RemoveMFAButton factoryId={factor.id} />
<RemoveMFAButton factorId={factor.id} />
</div>
);
});
Expand Down
43 changes: 27 additions & 16 deletions apps/dashboard/src/components/modals/add-new-device.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
"use client";

import { mfaVerifyAction } from "@/actions/mfa-verify-action";
import { createClient } from "@midday/supabase/client";
import { Button } from "@midday/ui/button";
import { Dialog, DialogContent } from "@midday/ui/dialog";
import { cn } from "@midday/ui/utils";
import { useAction } from "next-safe-action/hook";
import Image from "next/image";
import { usePathname, useRouter, useSearchParams } from "next/navigation";
import { useEffect, useState } from "react";
Expand All @@ -20,25 +22,21 @@ export function AddNewDeviceModal() {
const [qr, setQR] = useState("");
const isOpen = searchParams.get("add") === "device";

const verify = useAction(mfaVerifyAction, {
onSuccess: () => router.push(pathname),
});

const onComplete = async (code: string) => {
if (!isValidating) {
setValidating(true);

const challenge = await supabase.auth.mfa.challenge({ factorId });

try {
const verify = await supabase.auth.mfa.verify({
factorId,
challengeId: challenge.data.id,
code,
});

if (verify.data) {
router.push(pathname);
}
} catch {
setError(true);
}
verify.execute({
factorId,
challengeId: challenge.data.id,
code,
});
}
};

Expand All @@ -65,9 +63,22 @@ export function AddNewDeviceModal() {
}
}, [isOpen]);

const handleOnClose = () => {
router.push(pathname);

supabase.auth.mfa.unenroll({
factorId,
});
};

return (
<Dialog open={isOpen} onOpenChange={() => router.push(pathname)}>
<DialogContent className="max-w-[455px]">
<Dialog open={isOpen} onOpenChange={handleOnClose}>
<DialogContent
className="max-w-[455px]"
onInteractOutside={(evt) => {
evt.preventDefault();
}}
>
<div className="p-6">
<div className="flex items-center justify-center mt-8">
<div className="w-[190px] h-[190px] bg-white rounded-md">
Expand Down Expand Up @@ -96,7 +107,7 @@ export function AddNewDeviceModal() {

<div className="flex border-t-[1px] pt-4 mt-4 justify-center">
<Button
onClick={() => router.push(pathname)}
onClick={handleOnClose}
variant="ghost"
className="text-medium text-sm hover:bg-transparent"
>
Expand Down
6 changes: 3 additions & 3 deletions apps/dashboard/src/components/remove-mfa-button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ import { useToast } from "@midday/ui/use-toast";
import { useAction } from "next-safe-action/hook";

type Props = {
factoryId: string;
factorId: string;
};

export function RemoveMFAButton({ factoryId }: Props) {
export function RemoveMFAButton({ factorId }: Props) {
const { toast } = useToast();

const unenroll = useAction(unenrollMfaAction, {
Expand All @@ -23,7 +23,7 @@ export function RemoveMFAButton({ factoryId }: Props) {
});

return (
<Button variant="outline" onClick={() => unenroll.execute({ factoryId })}>
<Button variant="outline" onClick={() => unenroll.execute({ factorId })}>
Remove
</Button>
);
Expand Down

0 comments on commit 5d721d7

Please sign in to comment.