0.2.16-alpha.4 • Published 8 months ago
@bricco/auth v0.2.16-alpha.4
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