@liedsonc/core-auth-kit 0.1.0 → 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.
Files changed (35) hide show
  1. package/README.md +802 -759
  2. package/auth-ui/bin/init.js +126 -0
  3. package/auth-ui/components/auth-card.tsx +49 -49
  4. package/auth-ui/components/auth-form.tsx +53 -53
  5. package/auth-ui/components/error-message.tsx +24 -24
  6. package/auth-ui/components/form-field.tsx +39 -39
  7. package/auth-ui/components/loading-spinner.tsx +19 -19
  8. package/auth-ui/components/oauth-buttons.tsx +49 -49
  9. package/auth-ui/components/password-input.tsx +93 -93
  10. package/auth-ui/components/success-message.tsx +24 -24
  11. package/auth-ui/package.json +61 -55
  12. package/auth-ui/pages/forgot-password/index.tsx +83 -83
  13. package/auth-ui/pages/login/index.tsx +119 -119
  14. package/auth-ui/pages/register/index.tsx +149 -149
  15. package/auth-ui/pages/reset-password/index.tsx +133 -133
  16. package/auth-ui/pages/verify-email/index.tsx +143 -143
  17. package/auth-ui/templates/app/(auth)/forgot-password/page.tsx +5 -0
  18. package/auth-ui/templates/app/(auth)/layout.tsx +12 -0
  19. package/auth-ui/templates/app/(auth)/login/page.tsx +5 -0
  20. package/auth-ui/templates/app/(auth)/register/page.tsx +5 -0
  21. package/auth-ui/templates/app/(auth)/reset-password/page.tsx +5 -0
  22. package/auth-ui/templates/app/(auth)/verify-email/page.tsx +5 -0
  23. package/auth-ui/templates/app/api/auth/forgot-password/route.ts +16 -0
  24. package/auth-ui/templates/app/api/auth/login/route.ts +16 -0
  25. package/auth-ui/templates/app/api/auth/logout/route.ts +8 -0
  26. package/auth-ui/templates/app/api/auth/register/route.ts +16 -0
  27. package/auth-ui/templates/app/api/auth/reset-password/route.ts +16 -0
  28. package/auth-ui/templates/app/api/auth/session/route.ts +8 -0
  29. package/auth-ui/templates/app/api/auth/verify-email/route.ts +16 -0
  30. package/auth-ui/templates/env.example +25 -0
  31. package/auth-ui/templates/lib/auth-client.ts +20 -0
  32. package/auth-ui/templates/lib/auth-config.ts +43 -0
  33. package/auth-ui/tsconfig.json +4 -15
  34. package/package.json +17 -6
  35. package/tailwind.config.ts +41 -41
@@ -0,0 +1,16 @@
1
+ import { NextResponse } from "next/server";
2
+
3
+ export async function POST(request: Request) {
4
+ const body = await request.json().catch(() => ({}));
5
+ const { token, newPassword } = body as { token?: string; newPassword?: string };
6
+ if (!token || !newPassword) {
7
+ return NextResponse.json(
8
+ { error: "Missing token or newPassword" },
9
+ { status: 400 }
10
+ );
11
+ }
12
+ return NextResponse.json(
13
+ { error: "Implement this route: validate token and update password in your backend." },
14
+ { status: 501 }
15
+ );
16
+ }
@@ -0,0 +1,8 @@
1
+ import { NextResponse } from "next/server";
2
+
3
+ export async function GET() {
4
+ return NextResponse.json(
5
+ { error: "Implement this route: return current session (e.g. from cookie or token)." },
6
+ { status: 501 }
7
+ );
8
+ }
@@ -0,0 +1,16 @@
1
+ import { NextResponse } from "next/server";
2
+
3
+ export async function POST(request: Request) {
4
+ const body = await request.json().catch(() => ({}));
5
+ const { token } = body as { token?: string };
6
+ if (!token) {
7
+ return NextResponse.json(
8
+ { error: "Missing token" },
9
+ { status: 400 }
10
+ );
11
+ }
12
+ return NextResponse.json(
13
+ { error: "Implement this route: validate verification token and mark email verified in your backend." },
14
+ { status: 501 }
15
+ );
16
+ }
@@ -0,0 +1,25 @@
1
+ # App URL (used for redirects and OAuth)
2
+ NEXT_PUBLIC_APP_URL=http://localhost:3000
3
+
4
+ # Redirects after auth actions
5
+ NEXT_PUBLIC_AUTH_REDIRECT_AFTER_LOGIN=/
6
+ NEXT_PUBLIC_AUTH_REDIRECT_AFTER_REGISTER=/login
7
+ NEXT_PUBLIC_AUTH_REDIRECT_AFTER_RESET=/login
8
+
9
+ # Google OAuth
10
+ NEXT_PUBLIC_OAUTH_GOOGLE_ENABLED=false
11
+ NEXT_PUBLIC_OAUTH_GOOGLE_CLIENT_ID=your_google_client_id
12
+ NEXT_PUBLIC_OAUTH_GOOGLE_REDIRECT_URI=http://localhost:3000/api/auth/google
13
+ OAUTH_GOOGLE_CLIENT_SECRET=your_google_client_secret
14
+
15
+ # Apple OAuth
16
+ NEXT_PUBLIC_OAUTH_APPLE_ENABLED=false
17
+ NEXT_PUBLIC_OAUTH_APPLE_CLIENT_ID=your_apple_client_id
18
+ NEXT_PUBLIC_OAUTH_APPLE_REDIRECT_URI=http://localhost:3000/api/auth/apple
19
+ OAUTH_APPLE_CLIENT_SECRET=your_apple_client_secret
20
+
21
+ # Resend (optional, for verification and password reset emails)
22
+ RESEND_API_KEY=re_your_resend_api_key
23
+ RESEND_FROM_EMAIL=noreply@yourdomain.com
24
+ RESEND_FROM_NAME=Your App Name
25
+ NEXT_PUBLIC_APP_NAME=Your App Name
@@ -0,0 +1,20 @@
1
+ import type { AuthClient } from "@liedsonc/core-auth-kit";
2
+
3
+ const notImplemented = () =>
4
+ Promise.resolve({
5
+ success: false as const,
6
+ error: {
7
+ code: "NOT_IMPLEMENTED",
8
+ message: "Implement auth-client.ts with your backend (e.g. Supabase, custom API).",
9
+ },
10
+ });
11
+
12
+ export const authClient: AuthClient = {
13
+ login: notImplemented,
14
+ register: notImplemented,
15
+ logout: () => Promise.resolve(),
16
+ forgotPassword: notImplemented,
17
+ resetPassword: notImplemented,
18
+ verifyEmail: notImplemented,
19
+ getSession: () => Promise.resolve(null),
20
+ };
@@ -0,0 +1,43 @@
1
+ import type { AuthUIConfig, OAuthProvider } from "@liedsonc/core-auth-kit";
2
+ import { authClient } from "@/lib/auth-client";
3
+
4
+ export interface OAuthProviderConfig {
5
+ provider: OAuthProvider;
6
+ enabled: boolean;
7
+ clientId?: string;
8
+ redirectUri?: string;
9
+ }
10
+
11
+ export function getOAuthProvidersFromEnv(): OAuthProviderConfig[] {
12
+ const providers: OAuthProviderConfig[] = [];
13
+
14
+ if (process.env.NEXT_PUBLIC_OAUTH_GOOGLE_ENABLED === "true") {
15
+ providers.push({
16
+ provider: "google",
17
+ enabled: true,
18
+ clientId: process.env.NEXT_PUBLIC_OAUTH_GOOGLE_CLIENT_ID,
19
+ redirectUri: process.env.NEXT_PUBLIC_OAUTH_GOOGLE_REDIRECT_URI,
20
+ });
21
+ }
22
+
23
+ if (process.env.NEXT_PUBLIC_OAUTH_APPLE_ENABLED === "true") {
24
+ providers.push({
25
+ provider: "apple",
26
+ enabled: true,
27
+ clientId: process.env.NEXT_PUBLIC_OAUTH_APPLE_CLIENT_ID,
28
+ redirectUri: process.env.NEXT_PUBLIC_OAUTH_APPLE_REDIRECT_URI,
29
+ });
30
+ }
31
+
32
+ return providers;
33
+ }
34
+
35
+ export function getAuthUIConfig(): AuthUIConfig {
36
+ return {
37
+ authClient,
38
+ oauthProviders: getOAuthProvidersFromEnv(),
39
+ redirectAfterLogin: process.env.NEXT_PUBLIC_AUTH_REDIRECT_AFTER_LOGIN || "/",
40
+ redirectAfterRegister: process.env.NEXT_PUBLIC_AUTH_REDIRECT_AFTER_REGISTER || "/login",
41
+ redirectAfterReset: process.env.NEXT_PUBLIC_AUTH_REDIRECT_AFTER_RESET || "/login",
42
+ };
43
+ }
@@ -14,20 +14,9 @@
14
14
  "forceConsistentCasingInFileNames": true,
15
15
  "isolatedModules": true,
16
16
  "incremental": true,
17
- "plugins": [
18
- {
19
- "name": "next"
20
- }
21
- ],
22
- "paths": {
23
- "@/*": ["./*"]
24
- }
17
+ "plugins": [{ "name": "next" }],
18
+ "paths": { "@/*": ["./*"] }
25
19
  },
26
- "include": [
27
- "**/*.ts",
28
- "**/*.tsx"
29
- ],
30
- "exclude": [
31
- "node_modules"
32
- ]
20
+ "include": ["**/*.ts", "**/*.tsx"],
21
+ "exclude": ["node_modules", "templates", "bin"]
33
22
  }
package/package.json CHANGED
@@ -1,10 +1,12 @@
1
1
  {
2
2
  "name": "@liedsonc/core-auth-kit",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Production-ready authentication UI package for Next.js App Router",
5
5
  "scripts": {
6
- "build": "cd auth-ui && npm run build",
7
- "prepublishOnly": "npm run build"
6
+ "dev": "next dev",
7
+ "build": "npm run build --prefix auth-ui",
8
+ "start": "next start",
9
+ "lint": "next lint"
8
10
  },
9
11
  "keywords": [
10
12
  "nextjs",
@@ -17,9 +19,18 @@
17
19
  ],
18
20
  "author": "",
19
21
  "license": "MIT",
20
- "workspaces": [
21
- "auth-ui"
22
- ],
22
+ "dependencies": {
23
+ "@radix-ui/react-label": "^2.1.0",
24
+ "@radix-ui/react-slot": "^1.1.0",
25
+ "class-variance-authority": "^0.7.0",
26
+ "clsx": "^2.1.1",
27
+ "next": "^15.0.0",
28
+ "react": "^19.0.0",
29
+ "react-dom": "^19.0.0",
30
+ "resend": "^4.0.0",
31
+ "tailwind-merge": "^2.5.0",
32
+ "zod": "^3.23.0"
33
+ },
23
34
  "devDependencies": {
24
35
  "@types/node": "^22.0.0",
25
36
  "@types/react": "^19.0.0",
@@ -1,41 +1,41 @@
1
- import type { Config } from "tailwindcss";
2
-
3
- const config: Config = {
4
- darkMode: "class",
5
- content: [
6
- "./auth-ui/**/*.{js,ts,jsx,tsx,mdx}",
7
- ],
8
- theme: {
9
- extend: {
10
- colors: {
11
- background: "hsl(var(--background))",
12
- foreground: "hsl(var(--foreground))",
13
- card: "hsl(var(--card))",
14
- "card-foreground": "hsl(var(--card-foreground))",
15
- popover: "hsl(var(--popover))",
16
- "popover-foreground": "hsl(var(--popover-foreground))",
17
- primary: "hsl(var(--primary))",
18
- "primary-foreground": "hsl(var(--primary-foreground))",
19
- secondary: "hsl(var(--secondary))",
20
- "secondary-foreground": "hsl(var(--secondary-foreground))",
21
- muted: "hsl(var(--muted))",
22
- "muted-foreground": "hsl(var(--muted-foreground))",
23
- accent: "hsl(var(--accent))",
24
- "accent-foreground": "hsl(var(--accent-foreground))",
25
- destructive: "hsl(var(--destructive))",
26
- "destructive-foreground": "hsl(var(--destructive-foreground))",
27
- border: "hsl(var(--border))",
28
- input: "hsl(var(--input))",
29
- ring: "hsl(var(--ring))",
30
- },
31
- borderRadius: {
32
- lg: "var(--radius)",
33
- md: "calc(var(--radius) - 2px)",
34
- sm: "calc(var(--radius) - 4px)",
35
- },
36
- },
37
- },
38
- plugins: [],
39
- };
40
-
41
- export default config;
1
+ import type { Config } from "tailwindcss";
2
+
3
+ const config: Config = {
4
+ darkMode: "class",
5
+ content: [
6
+ "./auth-ui/**/*.{js,ts,jsx,tsx,mdx}",
7
+ ],
8
+ theme: {
9
+ extend: {
10
+ colors: {
11
+ background: "hsl(var(--background))",
12
+ foreground: "hsl(var(--foreground))",
13
+ card: "hsl(var(--card))",
14
+ "card-foreground": "hsl(var(--card-foreground))",
15
+ popover: "hsl(var(--popover))",
16
+ "popover-foreground": "hsl(var(--popover-foreground))",
17
+ primary: "hsl(var(--primary))",
18
+ "primary-foreground": "hsl(var(--primary-foreground))",
19
+ secondary: "hsl(var(--secondary))",
20
+ "secondary-foreground": "hsl(var(--secondary-foreground))",
21
+ muted: "hsl(var(--muted))",
22
+ "muted-foreground": "hsl(var(--muted-foreground))",
23
+ accent: "hsl(var(--accent))",
24
+ "accent-foreground": "hsl(var(--accent-foreground))",
25
+ destructive: "hsl(var(--destructive))",
26
+ "destructive-foreground": "hsl(var(--destructive-foreground))",
27
+ border: "hsl(var(--border))",
28
+ input: "hsl(var(--input))",
29
+ ring: "hsl(var(--ring))",
30
+ },
31
+ borderRadius: {
32
+ lg: "var(--radius)",
33
+ md: "calc(var(--radius) - 2px)",
34
+ sm: "calc(var(--radius) - 4px)",
35
+ },
36
+ },
37
+ },
38
+ plugins: [],
39
+ };
40
+
41
+ export default config;