@flaredev/cli 0.1.2 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +340 -163
- package/package.json +3 -2
- package/templates/app/app/api/openapi.json/route.ts +23 -0
- package/templates/app/app/api/reference/route.ts +36 -0
- package/templates/app/app/dashboard/account/page.tsx +38 -0
- package/templates/app/app/dashboard/layout.tsx +39 -0
- package/templates/app/app/dashboard/page.tsx +42 -9
- package/templates/app/app/forgot-password/page.tsx +22 -0
- package/templates/app/app/globals.css +109 -4
- package/templates/app/app/layout.tsx +28 -26
- package/templates/app/app/page.tsx +126 -13
- package/templates/app/app/reset-password/page.tsx +31 -0
- package/templates/app/app/sign-in/page.tsx +49 -33
- package/templates/app/app/sign-up/page.tsx +42 -23
- package/templates/app/app/two-factor/page.tsx +25 -0
- package/templates/app/components/account/security-settings.tsx +525 -0
- package/templates/app/components/admin/fields/country-field.tsx +152 -0
- package/templates/app/components/admin/fields/field-widget.tsx +186 -128
- package/templates/app/components/admin/fields/multi-select-field.tsx +46 -0
- package/templates/app/components/admin/fields/phone-field.tsx +86 -0
- package/templates/app/components/admin/resource-nav.tsx +120 -109
- package/templates/app/components/admin/resource-table.tsx +31 -1
- package/templates/app/components/auth/auth-shell.tsx +284 -0
- package/templates/app/components/auth/password-forms.tsx +79 -0
- package/templates/app/components/auth/provider-icons.tsx +39 -0
- package/templates/app/components/auth/sign-in-flow.tsx +315 -0
- package/templates/app/components/auth/sign-up-form.tsx +101 -0
- package/templates/app/components/auth/social-buttons.tsx +56 -0
- package/templates/app/components/auth/two-factor-form.tsx +124 -0
- package/templates/app/components/auth/ui.tsx +96 -0
- package/templates/app/components/dashboard/dashboard-nav.tsx +35 -0
- package/templates/app/components/marketing/product-preview.tsx +70 -0
- package/templates/app/components/marketing/site-header.tsx +39 -0
- package/templates/app/components/sign-out-button.tsx +1 -1
- package/templates/app/components/ui/checkbox.tsx +25 -0
- package/templates/app/components/ui/radio-group.tsx +29 -0
- package/templates/app/db/auth-schema.ts +167 -118
- package/templates/app/lib/admin-nav.ts +1 -1
- package/templates/app/lib/api-docs.ts +16 -0
- package/templates/app/lib/auth-client.ts +16 -1
- package/templates/app/lib/auth-config.ts +33 -0
- package/templates/app/lib/auth-emails.ts +94 -0
- package/templates/app/lib/auth.ts +81 -6
- package/templates/app/lib/site.ts +47 -0
- package/templates/app/lib/theme.ts +79 -0
- package/templates/app/migrations/0000_init.sql +32 -1
- package/templates/app/migrations/meta/0000_snapshot.json +215 -1
- package/templates/app/migrations/meta/_journal.json +1 -1
- package/templates/app/vite.config.ts +5 -3
- package/templates/app/components/auth-form.tsx +0 -120
|
@@ -1,33 +1,49 @@
|
|
|
1
|
-
import Link from "next/link";
|
|
2
|
-
import { redirect } from "next/navigation";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
1
|
+
import Link from "next/link";
|
|
2
|
+
import { redirect } from "next/navigation";
|
|
3
|
+
import { AuthShell } from "@/components/auth/auth-shell";
|
|
4
|
+
import { SignInFlow } from "@/components/auth/sign-in-flow";
|
|
5
|
+
import { enabledSocialProviders } from "@/lib/auth";
|
|
6
|
+
import { authConfig } from "@/lib/auth-config";
|
|
7
|
+
import { getSession, safeRedirectPath } from "@/lib/session";
|
|
8
|
+
import { site } from "@/lib/site";
|
|
9
|
+
import { theme } from "@/lib/theme";
|
|
10
|
+
|
|
11
|
+
export const metadata = { title: "Sign in" };
|
|
12
|
+
|
|
13
|
+
const ERRORS: Record<string, string> = {
|
|
14
|
+
oauth: "Sign-in with that provider didn't finish. Try again.",
|
|
15
|
+
link: "That sign-in link has expired or was already used. Ask for a new one.",
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export default async function SignInPage({ searchParams }: { searchParams: Promise<{ next?: string; error?: string; reset?: string }> }) {
|
|
19
|
+
const params = await searchParams;
|
|
20
|
+
const next = safeRedirectPath(params.next);
|
|
21
|
+
if (await getSession()) redirect(next);
|
|
22
|
+
|
|
23
|
+
const copy = theme.signIn(site.name);
|
|
24
|
+
return (
|
|
25
|
+
<AuthShell
|
|
26
|
+
page="sign-in"
|
|
27
|
+
title={copy.title}
|
|
28
|
+
subtitle={(copy as { subtitle?: string }).subtitle}
|
|
29
|
+
footer={
|
|
30
|
+
<>
|
|
31
|
+
Don't have an account?{" "}
|
|
32
|
+
<Link href={`/sign-up?next=${encodeURIComponent(next)}`} className="font-medium text-link hover:underline">
|
|
33
|
+
Sign up
|
|
34
|
+
</Link>
|
|
35
|
+
</>
|
|
36
|
+
}
|
|
37
|
+
>
|
|
38
|
+
<SignInFlow
|
|
39
|
+
providers={enabledSocialProviders()}
|
|
40
|
+
socialPlacement={theme.social}
|
|
41
|
+
socialStyle={theme.socialStyle}
|
|
42
|
+
methods={{ magicLink: authConfig.magicLink, emailOtp: authConfig.emailOtp, passkeys: authConfig.passkeys }}
|
|
43
|
+
next={next}
|
|
44
|
+
initialError={params.error ? (ERRORS[params.error] ?? "Sign-in didn't finish. Try again.") : null}
|
|
45
|
+
initialNotice={params.reset ? "Your password is changed. Sign in with the new one." : null}
|
|
46
|
+
/>
|
|
47
|
+
</AuthShell>
|
|
48
|
+
);
|
|
49
|
+
}
|
|
@@ -1,23 +1,42 @@
|
|
|
1
|
-
import Link from "next/link";
|
|
2
|
-
import { redirect } from "next/navigation";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
}
|
|
1
|
+
import Link from "next/link";
|
|
2
|
+
import { redirect } from "next/navigation";
|
|
3
|
+
import { AuthShell } from "@/components/auth/auth-shell";
|
|
4
|
+
import { SignUpForm } from "@/components/auth/sign-up-form";
|
|
5
|
+
import { enabledSocialProviders } from "@/lib/auth";
|
|
6
|
+
import { authConfig } from "@/lib/auth-config";
|
|
7
|
+
import { getSession, safeRedirectPath } from "@/lib/session";
|
|
8
|
+
import { site } from "@/lib/site";
|
|
9
|
+
import { theme } from "@/lib/theme";
|
|
10
|
+
|
|
11
|
+
export const metadata = { title: "Create an account" };
|
|
12
|
+
|
|
13
|
+
export default async function SignUpPage({ searchParams }: { searchParams: Promise<{ next?: string }> }) {
|
|
14
|
+
const params = await searchParams;
|
|
15
|
+
const next = safeRedirectPath(params.next);
|
|
16
|
+
if (await getSession()) redirect(next);
|
|
17
|
+
|
|
18
|
+
const copy = theme.signUp(site.name);
|
|
19
|
+
return (
|
|
20
|
+
<AuthShell
|
|
21
|
+
page="sign-up"
|
|
22
|
+
title={copy.title}
|
|
23
|
+
subtitle={(copy as { subtitle?: string }).subtitle}
|
|
24
|
+
footer={
|
|
25
|
+
<>
|
|
26
|
+
Already have an account?{" "}
|
|
27
|
+
<Link href={`/sign-in?next=${encodeURIComponent(next)}`} className="font-medium text-link hover:underline">
|
|
28
|
+
Sign in
|
|
29
|
+
</Link>
|
|
30
|
+
</>
|
|
31
|
+
}
|
|
32
|
+
>
|
|
33
|
+
<SignUpForm
|
|
34
|
+
providers={enabledSocialProviders()}
|
|
35
|
+
socialPlacement={theme.social}
|
|
36
|
+
socialStyle={theme.socialStyle}
|
|
37
|
+
next={next}
|
|
38
|
+
verifyFirst={authConfig.requireEmailVerification}
|
|
39
|
+
/>
|
|
40
|
+
</AuthShell>
|
|
41
|
+
);
|
|
42
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import Link from "next/link";
|
|
2
|
+
import { AuthShell } from "@/components/auth/auth-shell";
|
|
3
|
+
import { TwoFactorForm } from "@/components/auth/two-factor-form";
|
|
4
|
+
import { authConfig } from "@/lib/auth-config";
|
|
5
|
+
import { safeRedirectPath } from "@/lib/session";
|
|
6
|
+
|
|
7
|
+
export const metadata = { title: "Verify it's you" };
|
|
8
|
+
|
|
9
|
+
/** Reached after a correct password on an account with two-factor on (lib/auth-client.ts sends people here). */
|
|
10
|
+
export default async function TwoFactorPage({ searchParams }: { searchParams: Promise<{ next?: string }> }) {
|
|
11
|
+
const { next } = await searchParams;
|
|
12
|
+
return (
|
|
13
|
+
<AuthShell
|
|
14
|
+
title="Verify it's you"
|
|
15
|
+
subtitle="Your account uses two-factor authentication."
|
|
16
|
+
footer={
|
|
17
|
+
<Link href="/sign-in" className="font-medium text-link hover:underline">
|
|
18
|
+
Use a different account
|
|
19
|
+
</Link>
|
|
20
|
+
}
|
|
21
|
+
>
|
|
22
|
+
<TwoFactorForm methods={authConfig.twoFactor} next={safeRedirectPath(next)} />
|
|
23
|
+
</AuthShell>
|
|
24
|
+
);
|
|
25
|
+
}
|