auth in backend and frontend
This commit is contained in:
1 parent
39d2698f28
commit
9857acd4c1
65 files changed
+1632
-3923
No files matched your search
@@ -1,36 +1,30 @@
|
||||
{
|
||||
"name": "@mono/auth-api",
|
||||
"version": "0.1.0",
|
||||
"version": "0.0.1",
|
||||
"private": true,
|
||||
"main": "./dist/index.js",
|
||||
"module": "./dist/index.mjs",
|
||||
"types": "./dist/index.d.ts",
|
||||
"type": "commonjs",
|
||||
"exports": {
|
||||
".": {
|
||||
"require": "./dist/index.js",
|
||||
"import": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"build": "tsup src/index.ts --format cjs,esm --dts --clean --tsconfig tsconfig.json",
|
||||
"dev": "tsup src/index.ts --format cjs,esm --dts --watch --clean --tsconfig tsconfig.json",
|
||||
"clean": "rm -rf dist",
|
||||
"lint": "eslint src/",
|
||||
"check-types": "tsc --noEmit"
|
||||
"build": "tsc",
|
||||
"dev": "tsc --watch",
|
||||
"lint": "eslint .",
|
||||
"clean": "rm -rf dist"
|
||||
},
|
||||
"dependencies": {
|
||||
"@mono/auth-core": "0.1.0",
|
||||
"@nestjs/common": "^10.3.3",
|
||||
"@nestjs/jwt": "^10.2.0",
|
||||
"@nestjs/passport": "^10.0.3",
|
||||
"bcryptjs": "^2.4.3",
|
||||
"passport": "^0.7.0",
|
||||
"passport-jwt": "^4.0.1",
|
||||
"passport-local": "^1.0.0"
|
||||
"@mono/auth-core": "file:../auth-core",
|
||||
"@mono/database": "file:../database",
|
||||
"bcryptjs": "^2.4.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/bcryptjs": "^2.4.6",
|
||||
"@types/passport-jwt": "^4.0.1",
|
||||
"@types/passport-local": "^1.0.38",
|
||||
"tsup": "^8.0.2",
|
||||
"typescript": "^5.3.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@nestjs/common": "^10.0.0",
|
||||
"@nestjs/core": "^10.0.0"
|
||||
"@types/bcryptjs": "^2.4.6"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
import {
|
||||
Body,
|
||||
Controller,
|
||||
Post,
|
||||
UseGuards,
|
||||
Request,
|
||||
UnauthorizedException,
|
||||
HttpCode,
|
||||
HttpStatus,
|
||||
} from '@nestjs/common';
|
||||
import { AuthService } from './auth.service';
|
||||
import { LocalAuthGuard, JwtAuthGuard } from './guards';
|
||||
import { LoginDto, RegisterDto, RefreshTokenDto } from './dto/auth.dto';
|
||||
import { User } from '@mono/auth-core';
|
||||
|
||||
interface RequestWithUser {
|
||||
user: User;
|
||||
}
|
||||
|
||||
@Controller('auth')
|
||||
export class AuthController {
|
||||
constructor(private authService: AuthService) {}
|
||||
|
||||
@Post('register')
|
||||
async register(@Body() registerDto: RegisterDto) {
|
||||
const user = await this.authService.createUser(
|
||||
registerDto.email,
|
||||
registerDto.password,
|
||||
registerDto.name,
|
||||
);
|
||||
const tokens = await this.authService.generateTokens(user);
|
||||
return {
|
||||
user,
|
||||
...tokens,
|
||||
};
|
||||
}
|
||||
|
||||
@UseGuards(LocalAuthGuard)
|
||||
@Post('login')
|
||||
@HttpCode(HttpStatus.OK)
|
||||
async login(@Request() req: RequestWithUser, @Body() _loginDto: LoginDto) {
|
||||
const tokens = await this.authService.generateTokens(req.user);
|
||||
return {
|
||||
user: req.user,
|
||||
...tokens,
|
||||
};
|
||||
}
|
||||
|
||||
@Post('refresh')
|
||||
@HttpCode(HttpStatus.OK)
|
||||
async refresh(@Body() { refreshToken }: RefreshTokenDto) {
|
||||
try {
|
||||
const tokens = await this.authService.refreshTokens(refreshToken);
|
||||
return tokens;
|
||||
} catch (error) {
|
||||
throw new UnauthorizedException('Invalid refresh token');
|
||||
}
|
||||
}
|
||||
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@Post('logout')
|
||||
@HttpCode(HttpStatus.OK)
|
||||
async logout(@Body() { refreshToken }: RefreshTokenDto) {
|
||||
await this.authService.logout(refreshToken);
|
||||
return { message: 'Logged out successfully' };
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import { PassportModule } from '@nestjs/passport';
|
||||
import { AuthService } from './auth.service';
|
||||
import { JwtStrategy } from './strategies/jwt.strategy';
|
||||
import { LocalStrategy } from './strategies/local.strategy';
|
||||
import { AuthController } from './auth.controller';
|
||||
|
||||
export interface AuthModuleOptions {
|
||||
jwtSecret: string;
|
||||
@@ -22,6 +23,7 @@ export class AuthModule {
|
||||
signOptions: { expiresIn: options.jwtExpiresIn || '1h' },
|
||||
}),
|
||||
],
|
||||
controllers: [AuthController],
|
||||
providers: [
|
||||
AuthService,
|
||||
LocalStrategy,
|
||||
|
||||
@@ -1,12 +1,54 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { Injectable, UnauthorizedException } from '@nestjs/common';
|
||||
import { JwtService } from '@nestjs/jwt';
|
||||
import { User, AuthTokens } from '@mono/auth-core';
|
||||
import { prisma } from '@mono/database';
|
||||
import * as bcrypt from 'bcryptjs';
|
||||
|
||||
type UserWithPassword = User & { password: string };
|
||||
|
||||
interface SessionWithUser {
|
||||
id: string;
|
||||
userId: string;
|
||||
token: string;
|
||||
expiresAt: Date;
|
||||
user: {
|
||||
id: string;
|
||||
email: string;
|
||||
name: string | null;
|
||||
password: string;
|
||||
};
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class AuthService {
|
||||
constructor(private jwtService: JwtService) {}
|
||||
|
||||
async validateUser(email: string, password: string): Promise<User> {
|
||||
const user = await prisma.user.findUnique({
|
||||
where: { email },
|
||||
select: {
|
||||
id: true,
|
||||
email: true,
|
||||
password: true,
|
||||
name: true,
|
||||
}
|
||||
});
|
||||
if (!user) {
|
||||
throw new UnauthorizedException('Invalid credentials');
|
||||
}
|
||||
|
||||
const isPasswordValid = await this.validatePassword(password, user.password);
|
||||
if (!isPasswordValid) {
|
||||
throw new UnauthorizedException('Invalid credentials');
|
||||
}
|
||||
|
||||
const { password: _, ...result } = user;
|
||||
return {
|
||||
...result,
|
||||
name: result.name || undefined,
|
||||
};
|
||||
}
|
||||
|
||||
async validatePassword(password: string, hashedPassword: string): Promise<boolean> {
|
||||
return bcrypt.compare(password, hashedPassword);
|
||||
}
|
||||
@@ -15,16 +57,90 @@ export class AuthService {
|
||||
return bcrypt.hash(password, 10);
|
||||
}
|
||||
|
||||
async createUser(email: string, password: string, name?: string): Promise<User> {
|
||||
const existingUser = await prisma.user.findUnique({ where: { email } });
|
||||
if (existingUser) {
|
||||
throw new UnauthorizedException('Email already exists');
|
||||
}
|
||||
|
||||
const hashedPassword = await this.hashPassword(password);
|
||||
const user = await prisma.user.create({
|
||||
data: {
|
||||
email,
|
||||
password: hashedPassword,
|
||||
name: name || null,
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
email: true,
|
||||
name: true,
|
||||
},
|
||||
});
|
||||
|
||||
return {
|
||||
...user,
|
||||
name: user.name || undefined,
|
||||
};
|
||||
}
|
||||
|
||||
async generateTokens(user: User): Promise<AuthTokens> {
|
||||
const payload = { sub: user.id, email: user.email };
|
||||
const accessToken = this.jwtService.sign(payload);
|
||||
const refreshToken = this.jwtService.sign(payload, { expiresIn: '7d' });
|
||||
|
||||
// Store refresh token in sessions table
|
||||
await prisma.session.create({
|
||||
data: {
|
||||
userId: user.id,
|
||||
token: refreshToken,
|
||||
expiresAt: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000), // 7 days
|
||||
},
|
||||
});
|
||||
|
||||
return {
|
||||
accessToken: this.jwtService.sign(payload),
|
||||
refreshToken: this.jwtService.sign(payload, { expiresIn: '7d' }),
|
||||
accessToken,
|
||||
refreshToken,
|
||||
};
|
||||
}
|
||||
|
||||
async verifyToken(token: string): Promise<any> {
|
||||
return this.jwtService.verify(token);
|
||||
}
|
||||
|
||||
async refreshTokens(refreshToken: string): Promise<AuthTokens> {
|
||||
const session = await prisma.session.findUnique({
|
||||
where: { token: refreshToken },
|
||||
include: {
|
||||
user: {
|
||||
select: {
|
||||
id: true,
|
||||
email: true,
|
||||
name: true,
|
||||
password: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (!session || session.expiresAt < new Date()) {
|
||||
throw new UnauthorizedException('Invalid refresh token');
|
||||
}
|
||||
|
||||
// Delete the old session
|
||||
await prisma.session.delete({ where: { id: session.id } });
|
||||
|
||||
// Convert null to undefined for name and remove password
|
||||
const { password: _, ...userWithoutPassword } = session.user;
|
||||
const user: User = {
|
||||
...userWithoutPassword,
|
||||
name: userWithoutPassword.name || undefined,
|
||||
};
|
||||
|
||||
// Generate new tokens
|
||||
return this.generateTokens(user);
|
||||
}
|
||||
|
||||
async logout(refreshToken: string): Promise<void> {
|
||||
await prisma.session.delete({ where: { token: refreshToken } });
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
import { IsEmail, IsString, MinLength, IsOptional } from 'class-validator';
|
||||
|
||||
export class LoginDto {
|
||||
@IsEmail()
|
||||
email!: string;
|
||||
|
||||
@IsString()
|
||||
@MinLength(6)
|
||||
password!: string;
|
||||
}
|
||||
|
||||
export class RegisterDto {
|
||||
@IsEmail()
|
||||
email!: string;
|
||||
|
||||
@IsString()
|
||||
@MinLength(6)
|
||||
password!: string;
|
||||
|
||||
@IsString()
|
||||
@IsOptional()
|
||||
name?: string;
|
||||
}
|
||||
|
||||
export class RefreshTokenDto {
|
||||
@IsString()
|
||||
refreshToken!: string;
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from './jwt-auth.guard';
|
||||
export * from './local-auth.guard';
|
||||
@@ -0,0 +1,5 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { AuthGuard } from '@nestjs/passport';
|
||||
|
||||
@Injectable()
|
||||
export class JwtAuthGuard extends AuthGuard('jwt') {}
|
||||
@@ -0,0 +1,5 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { AuthGuard } from '@nestjs/passport';
|
||||
|
||||
@Injectable()
|
||||
export class LocalAuthGuard extends AuthGuard('local') {}
|
||||
@@ -1,10 +1,11 @@
|
||||
import { Injectable, Inject } from '@nestjs/common';
|
||||
import { PassportStrategy } from '@nestjs/passport';
|
||||
import { ExtractJwt, Strategy } from 'passport-jwt';
|
||||
import { prisma } from '@mono/database';
|
||||
|
||||
@Injectable()
|
||||
export class JwtStrategy extends PassportStrategy(Strategy) {
|
||||
constructor(@Inject('JWT_SECRET') jwtSecret: string) {
|
||||
constructor(@Inject('JWT_SECRET') private jwtSecret: string) {
|
||||
super({
|
||||
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
|
||||
ignoreExpiration: false,
|
||||
@@ -13,6 +14,14 @@ export class JwtStrategy extends PassportStrategy(Strategy) {
|
||||
}
|
||||
|
||||
async validate(payload: any) {
|
||||
return { id: payload.sub, email: payload.email };
|
||||
const user = await prisma.user.findUnique({
|
||||
where: { id: payload.sub },
|
||||
select: {
|
||||
id: true,
|
||||
email: true,
|
||||
name: true,
|
||||
},
|
||||
});
|
||||
return user;
|
||||
}
|
||||
}
|
||||
@@ -1,15 +1,21 @@
|
||||
import { Injectable, UnauthorizedException } from '@nestjs/common';
|
||||
import { PassportStrategy } from '@nestjs/passport';
|
||||
import { Strategy } from 'passport-local';
|
||||
import { AuthService } from '../auth.service';
|
||||
|
||||
@Injectable()
|
||||
export class LocalStrategy extends PassportStrategy(Strategy) {
|
||||
constructor() {
|
||||
super({ usernameField: 'email' });
|
||||
constructor(private authService: AuthService) {
|
||||
super({
|
||||
usernameField: 'email',
|
||||
});
|
||||
}
|
||||
|
||||
async validate(email: string, password: string): Promise<any> {
|
||||
// This method should be overridden in the implementing application
|
||||
throw new UnauthorizedException('Strategy not implemented');
|
||||
async validate(email: string, password: string) {
|
||||
const user = await this.authService.validateUser(email, password);
|
||||
if (!user) {
|
||||
throw new UnauthorizedException();
|
||||
}
|
||||
return user;
|
||||
}
|
||||
}
|
||||
@@ -3,18 +3,27 @@
|
||||
"compilerOptions": {
|
||||
"outDir": "./dist",
|
||||
"rootDir": "./src",
|
||||
"composite": true,
|
||||
"declaration": true,
|
||||
"declarationMap": true,
|
||||
"tsBuildInfoFile": "./dist/.tsbuildinfo",
|
||||
"experimentalDecorators": true,
|
||||
"emitDecoratorMetadata": true,
|
||||
"composite": true,
|
||||
"incremental": true,
|
||||
"module": "commonjs",
|
||||
"target": "es2020",
|
||||
"moduleResolution": "node",
|
||||
"esModuleInterop": true,
|
||||
"skipLibCheck": true,
|
||||
"baseUrl": "../..",
|
||||
"paths": {
|
||||
"@mono/auth-core": ["packages/auth-core/src"],
|
||||
"@mono/auth-core/*": ["packages/auth-core/src/*"]
|
||||
"@mono/database": ["packages/database/src"]
|
||||
}
|
||||
},
|
||||
"include": ["src"],
|
||||
"include": ["src/**/*"],
|
||||
"exclude": ["dist", "node_modules"],
|
||||
"references": [
|
||||
{ "path": "../auth-core" }
|
||||
{ "path": "../auth-core" },
|
||||
{ "path": "../database" }
|
||||
]
|
||||
}
|
||||
@@ -1 +1 @@
|
||||
{"fileNames":["../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es5.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2015.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2016.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2017.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2018.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2019.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2020.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2021.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2022.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2023.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2024.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.esnext.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.dom.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.dom.iterable.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2015.core.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2015.collection.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2015.generator.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2015.iterable.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2015.promise.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2015.proxy.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2015.reflect.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2015.symbol.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2016.array.include.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2016.intl.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2017.arraybuffer.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2017.date.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2017.object.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2017.string.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2017.intl.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2017.typedarrays.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2018.asynciterable.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2018.intl.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2018.promise.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2018.regexp.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2019.array.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2019.object.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2019.string.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2019.symbol.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2019.intl.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2020.bigint.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2020.date.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2020.promise.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2020.string.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2020.intl.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2020.number.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2021.promise.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/libLine truncated
|
||||
{"fileNames":["../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es5.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2015.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2016.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2017.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2018.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2019.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2020.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2021.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2022.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2023.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2024.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.esnext.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.dom.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.dom.iterable.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2015.core.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2015.collection.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2015.generator.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2015.iterable.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2015.promise.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2015.proxy.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2015.reflect.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2015.symbol.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2016.array.include.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2016.intl.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2017.arraybuffer.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2017.date.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2017.object.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2017.string.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2017.intl.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2017.typedarrays.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2018.asynciterable.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2018.intl.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2018.promise.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2018.regexp.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2019.array.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2019.object.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2019.string.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2019.symbol.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2019.intl.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2020.bigint.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2020.date.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2020.promise.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2020.string.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2020.intl.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2020.number.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/lib.es2021.promise.d.ts","../../../../.nvm/versions/node/v22.13.1/lib/node_modules/typescript/lib/libLine truncated
|
||||
@@ -6,18 +6,15 @@
|
||||
"module": "./dist/index.mjs",
|
||||
"types": "./dist/index.d.ts",
|
||||
"scripts": {
|
||||
"build": "tsup src/index.ts --format cjs,esm --dts --clean --tsconfig tsconfig.json",
|
||||
"dev": "tsup src/index.ts --format cjs,esm --dts --watch --clean --tsconfig tsconfig.json",
|
||||
"clean": "rm -rf dist",
|
||||
"lint": "eslint src/",
|
||||
"check-types": "tsc --noEmit"
|
||||
"build": "tsc",
|
||||
"dev": "tsc --watch",
|
||||
"lint": "eslint .",
|
||||
"clean": "rm -rf dist"
|
||||
},
|
||||
"dependencies": {
|
||||
"zod": "^3.22.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"tsup": "^8.0.2",
|
||||
"typescript": "^5.3.3",
|
||||
"@types/node": "^20.11.24"
|
||||
"typescript": "^5.3.3"
|
||||
}
|
||||
}
|
||||
@@ -1 +1,2 @@
|
||||
export * from './types';
|
||||
export * from './schemas/auth.schema';
|
||||
@@ -0,0 +1,12 @@
|
||||
import { z } from 'zod';
|
||||
|
||||
export const LoginSchema = z.object({
|
||||
email: z.string().email('Invalid email address'),
|
||||
password: z.string().min(6, 'Password must be at least 6 characters'),
|
||||
});
|
||||
|
||||
export const RegisterSchema = z.object({
|
||||
email: z.string().email('Invalid email address'),
|
||||
password: z.string().min(6, 'Password must be at least 6 characters'),
|
||||
name: z.string().optional(),
|
||||
});
|
||||
@@ -6,7 +6,8 @@
|
||||
"composite": true,
|
||||
"declaration": true,
|
||||
"declarationMap": true,
|
||||
"incremental": true
|
||||
"tsBuildInfoFile": "./dist/.tsbuildinfo"
|
||||
},
|
||||
"include": ["src"]
|
||||
"include": ["src/**/*.ts", "src/**/*.tsx"],
|
||||
"exclude": ["dist", "node_modules"]
|
||||
}
|
||||
@@ -1,33 +1,27 @@
|
||||
{
|
||||
"name": "@mono/auth-ui",
|
||||
"version": "0.1.0",
|
||||
"version": "0.0.1",
|
||||
"private": true,
|
||||
"main": "./dist/index.js",
|
||||
"module": "./dist/index.mjs",
|
||||
"types": "./dist/index.d.ts",
|
||||
"scripts": {
|
||||
"build": "tsup src/index.tsx --format cjs,esm --dts",
|
||||
"dev": "tsup src/index.tsx --format cjs,esm --dts --watch",
|
||||
"clean": "rm -rf dist",
|
||||
"lint": "eslint src/",
|
||||
"check-types": "tsc --noEmit"
|
||||
"build": "tsc",
|
||||
"dev": "tsc --watch",
|
||||
"lint": "eslint .",
|
||||
"clean": "rm -rf dist"
|
||||
},
|
||||
"dependencies": {
|
||||
"@hookform/resolvers": "^3.10.0",
|
||||
"@mono/auth-core": "0.1.0",
|
||||
"react-hook-form": "^7.50.0",
|
||||
"zod": "^3.24.2",
|
||||
"zustand": "^4.5.0"
|
||||
"@mono/auth-core": "file:../auth-core",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-hook-form": "^7.51.0",
|
||||
"@hookform/resolvers": "^3.3.4",
|
||||
"zod": "^3.22.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/react": "^18.2.55",
|
||||
"@types/react-dom": "^18.2.19",
|
||||
"tsup": "^8.0.2",
|
||||
"@types/react": "^18.2.64",
|
||||
"@types/react-dom": "^18.2.21",
|
||||
"typescript": "^5.3.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"next": "^14.0.0",
|
||||
"react": "^18.0.0",
|
||||
"react-dom": "^18.0.0"
|
||||
}
|
||||
}
|
||||
@@ -3,11 +3,18 @@
|
||||
"compilerOptions": {
|
||||
"outDir": "./dist",
|
||||
"rootDir": "./src",
|
||||
"jsx": "react-jsx",
|
||||
"composite": true,
|
||||
"preserveSymlinks": true
|
||||
"declaration": true,
|
||||
"declarationMap": true,
|
||||
"tsBuildInfoFile": "./dist/.tsbuildinfo",
|
||||
"jsx": "react-jsx",
|
||||
"baseUrl": "../..",
|
||||
"paths": {
|
||||
"@mono/auth-core": ["packages/auth-core/src"]
|
||||
}
|
||||
},
|
||||
"include": ["src"],
|
||||
"include": ["src/**/*"],
|
||||
"exclude": ["dist", "node_modules"],
|
||||
"references": [
|
||||
{ "path": "../auth-core" }
|
||||
]
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"name": "@mono/database",
|
||||
"version": "0.0.1",
|
||||
"private": true,
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
"scripts": {
|
||||
"build": "tsc",
|
||||
"db:generate": "prisma generate",
|
||||
"db:push": "prisma db push --skip-generate",
|
||||
"db:studio": "prisma studio"
|
||||
},
|
||||
"dependencies": {
|
||||
"@prisma/client": "^5.10.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"prisma": "^5.10.0",
|
||||
"typescript": "^5.3.3"
|
||||
}
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
-- CreateTable
|
||||
CREATE TABLE "users" (
|
||||
"id" TEXT NOT NULL,
|
||||
"email" TEXT NOT NULL,
|
||||
"password" TEXT NOT NULL,
|
||||
"name" TEXT,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "users_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "sessions" (
|
||||
"id" TEXT NOT NULL,
|
||||
"userId" TEXT NOT NULL,
|
||||
"token" TEXT NOT NULL,
|
||||
"expiresAt" TIMESTAMP(3) NOT NULL,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "sessions_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "users_email_key" ON "users"("email");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "sessions_token_key" ON "sessions"("token");
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "sessions" ADD CONSTRAINT "sessions_userId_fkey" FOREIGN KEY ("userId") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
@@ -0,0 +1,3 @@
|
||||
# Please do not edit this file manually
|
||||
# It should be added in your version-control system (i.e. Git)
|
||||
provider = "postgresql"
|
||||
@@ -0,0 +1,31 @@
|
||||
generator client {
|
||||
provider = "prisma-client-js"
|
||||
}
|
||||
|
||||
datasource db {
|
||||
provider = "postgresql"
|
||||
url = env("DATABASE_URL")
|
||||
}
|
||||
|
||||
model User {
|
||||
id String @id @default(cuid())
|
||||
email String @unique
|
||||
password String
|
||||
name String?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
sessions Session[]
|
||||
|
||||
@@map("users")
|
||||
}
|
||||
|
||||
model Session {
|
||||
id String @id @default(cuid())
|
||||
userId String
|
||||
token String @unique
|
||||
expiresAt DateTime
|
||||
createdAt DateTime @default(now())
|
||||
user User @relation(fields: [userId], references: [id])
|
||||
|
||||
@@map("sessions")
|
||||
}
|
||||
Vendored
+4
@@ -0,0 +1,4 @@
|
||||
import { PrismaClient } from '@prisma/client';
|
||||
export * from '@prisma/client';
|
||||
export declare const prisma: PrismaClient<import(".prisma/client").Prisma.PrismaClientOptions, never, import("@prisma/client/runtime/library").DefaultArgs>;
|
||||
//# sourceMappingURL=index.d.ts.map
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C,cAAc,gBAAgB,CAAC;AAM/B,eAAO,MAAM,MAAM,gIAIf,CAAC"}
|
||||
@@ -0,0 +1,9 @@
|
||||
var _a;
|
||||
import { PrismaClient } from '@prisma/client';
|
||||
export * from '@prisma/client';
|
||||
const globalForPrisma = globalThis;
|
||||
export const prisma = (_a = globalForPrisma.prisma) !== null && _a !== void 0 ? _a : new PrismaClient({
|
||||
log: process.env.NODE_ENV === 'development' ? ['query', 'error', 'warn'] : ['error'],
|
||||
});
|
||||
if (process.env.NODE_ENV !== 'production')
|
||||
globalForPrisma.prisma = prisma;
|
||||
@@ -0,0 +1,15 @@
|
||||
import { PrismaClient } from '@prisma/client';
|
||||
|
||||
export * from '@prisma/client';
|
||||
|
||||
const globalForPrisma = globalThis as unknown as {
|
||||
prisma: PrismaClient | undefined;
|
||||
};
|
||||
|
||||
export const prisma =
|
||||
globalForPrisma.prisma ??
|
||||
new PrismaClient({
|
||||
log: process.env.NODE_ENV === 'development' ? ['query', 'error', 'warn'] : ['error'],
|
||||
});
|
||||
|
||||
if (process.env.NODE_ENV !== 'production') globalForPrisma.prisma = prisma;
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "./dist",
|
||||
"rootDir": "./src"
|
||||
},
|
||||
"include": ["src"]
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
{"fileNames":["../../node_modules/typescript/lib/lib.es5.d.ts","../../node_modules/typescript/lib/lib.es2015.d.ts","../../node_modules/typescript/lib/lib.es2016.d.ts","../../node_modules/typescript/lib/lib.es2017.d.ts","../../node_modules/typescript/lib/lib.es2018.d.ts","../../node_modules/typescript/lib/lib.es2019.d.ts","../../node_modules/typescript/lib/lib.es2020.d.ts","../../node_modules/typescript/lib/lib.es2021.d.ts","../../node_modules/typescript/lib/lib.es2022.d.ts","../../node_modules/typescript/lib/lib.es2023.d.ts","../../node_modules/typescript/lib/lib.es2024.d.ts","../../node_modules/typescript/lib/lib.esnext.d.ts","../../node_modules/typescript/lib/lib.dom.d.ts","../../node_modules/typescript/lib/lib.dom.iterable.d.ts","../../node_modules/typescript/lib/lib.es2015.core.d.ts","../../node_modules/typescript/lib/lib.es2015.collection.d.ts","../../node_modules/typescript/lib/lib.es2015.generator.d.ts","../../node_modules/typescript/lib/lib.es2015.iterable.d.ts","../../node_modules/typescript/lib/lib.es2015.promise.d.ts","../../node_modules/typescript/lib/lib.es2015.proxy.d.ts","../../node_modules/typescript/lib/lib.es2015.reflect.d.ts","../../node_modules/typescript/lib/lib.es2015.symbol.d.ts","../../node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts","../../node_modules/typescript/lib/lib.es2016.array.include.d.ts","../../node_modules/typescript/lib/lib.es2016.intl.d.ts","../../node_modules/typescript/lib/lib.es2017.arraybuffer.d.ts","../../node_modules/typescript/lib/lib.es2017.date.d.ts","../../node_modules/typescript/lib/lib.es2017.object.d.ts","../../node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts","../../node_modules/typescript/lib/lib.es2017.string.d.ts","../../node_modules/typescript/lib/lib.es2017.intl.d.ts","../../node_modules/typescript/lib/lib.es2017.typedarrays.d.ts","../../node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts","../../node_modules/typescript/lib/lib.es2018.asynciterable.d.ts","../../node_modules/typescript/lib/lib.es2018.intl.d.ts","../../node_modules/typescript/lib/lib.es2018.promise.d.ts","../../node_modules/typescript/lib/lib.es2018.regexp.d.ts","../../node_modules/typescript/lib/lib.es2019.array.d.ts","../../node_modules/typescript/lib/lib.es2019.object.d.ts","../../node_modules/typescript/lib/lib.es2019.string.d.ts","../../node_modules/typescript/lib/lib.es2019.symbol.d.ts","../../node_modules/typescript/lib/lib.es2019.intl.d.ts","../../node_modules/typescript/lib/lib.es2020.bigint.d.ts","../../node_modules/typescript/lib/lib.es2020.date.d.ts","../../node_modules/typescript/lib/lib.es2020.promise.d.ts","../../node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts","../../node_modules/typescript/lib/lib.es2020.string.d.ts","../../node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts","../../node_modules/typescript/lib/lib.es2020.intl.d.ts","../../node_modules/typescript/lib/lib.es2020.number.d.ts","../../node_modules/typescript/lib/lib.es2021.promise.d.ts","../../node_modules/typescript/lib/lib.es2021.string.d.ts","../../node_modules/typescript/lib/lib.es2021.weakref.d.ts","../../node_modules/typescript/lib/lib.es2021.intl.d.ts","../../node_modules/typescript/lib/lib.es2022.array.d.ts","../../node_modules/typescript/lib/lib.es2022.error.d.ts","../../node_modules/typescript/lib/lib.es2022.intl.d.ts","../../node_modules/typescript/lib/lib.es2022.object.d.ts","../../node_modules/typescript/lib/lib.es2022.string.d.ts","../../node_modules/typescript/lib/lib.es2022.regexp.d.ts","../../node_modules/typescript/lib/lib.es2023.array.d.ts","../../node_modules/typescript/lib/lib.es2023.collection.d.ts","../../node_modules/typescript/lib/lib.es2023.intl.d.ts","../../node_modules/typescript/lib/lib.es2024.arraybuffer.d.ts","../../node_modules/typescript/lib/lib.es2024.collection.d.ts","../../node_modules/typescript/lib/lib.es2024.object.d.ts","../../node_modules/typescript/lib/lib.es2024.promise.d.ts","../../node_modules/typescript/lib/lib.es2024.regexp.d.ts","../../node_modules/typescript/lib/lib.es2024.sharedmemory.d.ts","../../node_modules/typescript/lib/lib.es2024.string.d.ts","../../node_modules/typescript/lib/lib.esnext.array.d.ts","../../node_modules/typescript/lib/lib.esnext.collection.d.ts","../../node_modules/typescript/lib/lib.esnext.intl.d.ts","../../node_modules/typescript/lib/lib.esnext.disposable.d.ts","../../node_modules/typescript/lib/lib.esnext.promise.d.ts","../../node_modules/typescript/lib/lib.esnext.decorators.d.ts","../../node_modules/typescript/lib/lib.esnext.iterator.d.ts","../../node_modules/typescript/lib/lib.esnext.float16.d.ts","../../node_modules/typescript/lib/lib.decorators.d.ts","../../node_modules/typescript/lib/lib.decorators.legacy.d.ts","../../node_modules/@prisma/client/runtime/library.d.ts","../../node_modules/.prisma/client/index.d.ts","../../node_modules/.prisma/client/default.d.ts","../../node_modules/@prisma/client/default.d.ts","./src/index.ts","../../node_modules/@babel/types/lib/index.d.ts","../../noLine truncated
|
||||
Reference in new issue
Block a user