0.2.16-alpha.4 • Published 8 months ago

@bricco/auth v0.2.16-alpha.4

Weekly downloads
-
License
MIT
Repository
-
Last release
8 months ago

How to implement

  • Create a middleware.ts file (or extend the current file)
import { NextRequest, NextResponse } from 'next/server';
import { auth } from '@/services/auth';

export async function middleware(request: NextRequest ): Promise<NextResponse | void> {
  const url = request.nextUrl.clone();

  // Only validate the user if the request is not for a static asset
  // Add more paths here which should ignore auth
  if (!url.pathname.startsWith('/_next/static')) {
    const user = await auth();
    if (!user && url.pathname !== '/admin/login' && !url.pathname.startsWith('/api/auth')) {
      console.info(`No user found, redirecting from ${url.pathname} to /admin/login`);
      url.pathname = '/admin/login';
      return NextResponse.redirect(url);
    }
  }
  return NextResponse.next();
}
  • Create a @/services/auth file
import { createAuth, type Credentials, encodePassword, VercelKVAdapter } from '@bricco/auth';
import { z } from 'zod';

// Optional to extend credentials
export type CredentialsWith2FA = Credentials & {
  twoFactorAuth?: string;
};

// The user model for the JWT cookie
type UserModel = {
  _id: string;
  email: string;
  company: string;
};

// Parsing schema for login data
export const signInSchema = z.object({
  email: z.string().email(),
  password: z
    .string()
    .min(1)
    .transform(value => encodePassword(value)),
  twoFactorAuth: z.string().optional(),
});

// Authorize function
const authorize = async (credentials: Partial<CredentialsWith2FA>): Promise<Partial<UserModel> | null> => {
  const loginUser = await signInSchema.parseAsync(credentials);
  if (!loginUser) {
    throw new Error('User not found.');
  }

  // Do your auth here
  const user = { _id: '123', email: loginUser.email, company: 'Bricco', twoVerified: false };

  // Return the user
  return { _id: user._id, email: user.email, company: user.company };
};

export const { signIn, auth, handlers } = createAuth<CredentialsWith2FA, UserModel>({
  authorize,
  adapter: VercelKVAdapter({}),
});
  • Create optional actions (@services/action.ts)
'use server';

import { signIn } from './auth';

/**
 * Login via server action
 * @param data FormData with email and password
 */
export const login = async (data: FormData): Promise<void> => {
  await signIn('credentials', {
    email: data.get('email') as string,
    password: data.get('password') as string,
    redirectTo: '/admin',
  });
};
  • Create optinal login form (/admin/login/page.tsx)
'use client';

import { login } from '@/services/action';

export default function Login(): JSX.Element {
  return (
    <div>
      <h1>Login</h1>
      <form action={login}>
        <input name="email" defaultValue="test@email.com" />
        <input name="password" type="password" defaultValue="randompassword" />
        <input type="submit" value="Login" />
      </form>
    </div>
  );
}
  • The package includes a AuthProvider is you want to access the session in client components (/admin/layout.tsx)
  <AuthProvider session={(await auth()) as any}>{children}</AuthProvider>
0.2.16-alpha.4

8 months ago

0.2.16-alpha.3

8 months ago

0.2.16-alpha.2

8 months ago

0.2.16-alpha.1

8 months ago

0.2.19

9 months ago

0.2.18

9 months ago

0.2.17

9 months ago

0.2.16

9 months ago

0.2.16-alpha.0

9 months ago

0.2.15

9 months ago

0.2.14

10 months ago

0.2.13

10 months ago

0.2.12

10 months ago

0.2.11

10 months ago

0.2.10

10 months ago

0.2.1

1 year ago

0.2.0

1 year ago

0.1.1

1 year ago

0.2.7

11 months ago

0.2.6

1 year ago

0.2.9

11 months ago

0.2.8

11 months ago

0.2.3

1 year ago

0.2.2

1 year ago

2.0.1

10 months ago

0.2.5

1 year ago

0.2.4

1 year ago

0.1.0

1 year ago

0.1.0-alpha.0

1 year ago

0.0.19

1 year ago

0.0.18

1 year ago