Compare commits
No commits in common. "d4a9519cbfb8d8f945e062b147dc4703c6d09262" and "3f61a16324ce5223a1eb47e26304558d45c3d0b4" have entirely different histories.
d4a9519cbf
...
3f61a16324
21
biome.json
21
biome.json
@ -4,27 +4,22 @@
|
|||||||
"enabled": false
|
"enabled": false
|
||||||
},
|
},
|
||||||
"linter": {
|
"linter": {
|
||||||
"enabled": false,
|
"enabled": true,
|
||||||
"rules": {
|
"rules": {
|
||||||
"recommended": true,
|
"recommended": true,
|
||||||
"performance": {
|
"performance": {
|
||||||
"recommended": true
|
"recommended": true
|
||||||
},
|
},
|
||||||
"security": {
|
"security": {
|
||||||
"recommended": true
|
"recommended": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"formatter": {
|
"formatter": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"indentStyle": "space",
|
"indentStyle": "space",
|
||||||
"indentWidth": 2,
|
"indentWidth": 2,
|
||||||
"lineWidth": 80,
|
"lineWidth": 80,
|
||||||
"formatWithErrors": false
|
"formatWithErrors": false
|
||||||
},
|
|
||||||
"javascript": {
|
|
||||||
"parser": {
|
|
||||||
"unsafeParameterDecoratorsEnabled": true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -24,9 +24,6 @@
|
|||||||
"@nestjs/core": "^10.0.0",
|
"@nestjs/core": "^10.0.0",
|
||||||
"@nestjs/platform-express": "^10.0.0",
|
"@nestjs/platform-express": "^10.0.0",
|
||||||
"@prisma/client": "^5.10.2",
|
"@prisma/client": "^5.10.2",
|
||||||
"argon2": "^0.40.1",
|
|
||||||
"class-transformer": "^0.5.1",
|
|
||||||
"class-validator": "^0.14.1",
|
|
||||||
"reflect-metadata": "^0.2.0",
|
"reflect-metadata": "^0.2.0",
|
||||||
"rxjs": "^7.8.1"
|
"rxjs": "^7.8.1"
|
||||||
},
|
},
|
||||||
|
@ -1,43 +0,0 @@
|
|||||||
/*
|
|
||||||
Warnings:
|
|
||||||
|
|
||||||
- You are about to drop the `Bookmark` table. If the table is not empty, all the data it contains will be lost.
|
|
||||||
- You are about to drop the `User` table. If the table is not empty, all the data it contains will be lost.
|
|
||||||
|
|
||||||
*/
|
|
||||||
-- DropTable
|
|
||||||
DROP TABLE `Bookmark`;
|
|
||||||
|
|
||||||
-- DropTable
|
|
||||||
DROP TABLE `User`;
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE `users` (
|
|
||||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
|
||||||
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
|
||||||
`updatedAt` DATETIME(3) NOT NULL,
|
|
||||||
`email` VARCHAR(191) NOT NULL,
|
|
||||||
`hash` VARCHAR(191) NOT NULL,
|
|
||||||
`firstName` VARCHAR(191) NULL,
|
|
||||||
`lastName` VARCHAR(191) NULL,
|
|
||||||
|
|
||||||
UNIQUE INDEX `users_id_key`(`id`),
|
|
||||||
UNIQUE INDEX `users_email_key`(`email`),
|
|
||||||
PRIMARY KEY (`id`)
|
|
||||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
|
||||||
|
|
||||||
-- CreateTable
|
|
||||||
CREATE TABLE `bookmarks` (
|
|
||||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
|
||||||
`createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
|
||||||
`updatedAt` DATETIME(3) NOT NULL,
|
|
||||||
`title` VARCHAR(191) NOT NULL,
|
|
||||||
`description` VARCHAR(191) NULL,
|
|
||||||
`link` VARCHAR(191) NOT NULL,
|
|
||||||
`userId` INTEGER NOT NULL,
|
|
||||||
|
|
||||||
PRIMARY KEY (`id`)
|
|
||||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
|
||||||
|
|
||||||
-- AddForeignKey
|
|
||||||
ALTER TABLE `bookmarks` ADD CONSTRAINT `bookmarks_userId_fkey` FOREIGN KEY (`userId`) REFERENCES `users`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
@ -14,18 +14,15 @@ datasource db {
|
|||||||
}
|
}
|
||||||
|
|
||||||
model User {
|
model User {
|
||||||
id Int @id @unique @default(autoincrement())
|
id Int @id @default(autoincrement())
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
updatedAt DateTime @updatedAt
|
updatedAt DateTime @updatedAt
|
||||||
|
|
||||||
email String @unique
|
email String
|
||||||
hash String
|
hash String
|
||||||
|
|
||||||
firstName String?
|
firstName String?
|
||||||
lastName String?
|
lastName String?
|
||||||
|
|
||||||
@@map("users")
|
|
||||||
bookmarks Bookmark[]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
model Bookmark {
|
model Bookmark {
|
||||||
@ -36,9 +33,4 @@ model Bookmark {
|
|||||||
title String
|
title String
|
||||||
description String?
|
description String?
|
||||||
link String
|
link String
|
||||||
|
|
||||||
userId Int
|
|
||||||
user User @relation(fields: [userId], references: [id])
|
|
||||||
|
|
||||||
@@map("bookmarks")
|
|
||||||
}
|
}
|
||||||
|
@ -4,15 +4,17 @@ import { AuthDto } from "./dto";
|
|||||||
|
|
||||||
@Controller('auth')
|
@Controller('auth')
|
||||||
export class AuthController {
|
export class AuthController {
|
||||||
constructor(private authService: AuthService) {}
|
constructor(private authService: AuthService) {}
|
||||||
|
|
||||||
@Post("register")
|
@Post('signup')
|
||||||
async signup(@Body() dto: AuthDto) {
|
signup(@Body() dto: AuthDto) {
|
||||||
return await this.authService.register(dto);
|
console.log({dto});
|
||||||
}
|
return this.authService.signup()
|
||||||
|
}
|
||||||
|
|
||||||
@Post("login")
|
@Post('signin')
|
||||||
async signin(@Body() dto: AuthDto) {
|
signin(@Body() dto: AuthDto) {
|
||||||
return await this.authService.login(dto);
|
console.log({dto});
|
||||||
}
|
return this.authService.signin()
|
||||||
|
}
|
||||||
}
|
}
|
@ -1,60 +1,17 @@
|
|||||||
import { ForbiddenException, Injectable } from "@nestjs/common";
|
import { Injectable } from "@nestjs/common";
|
||||||
import { PrismaService } from "src/prisma/prisma.service";
|
import { PrismaService } from "src/prisma/prisma.service";
|
||||||
import { AuthDto } from "./dto";
|
|
||||||
import * as argon from "argon2";
|
|
||||||
import { PrismaClientKnownRequestError } from "@prisma/client/runtime/library";
|
|
||||||
|
|
||||||
@Injectable({})
|
@Injectable({})
|
||||||
export class AuthService {
|
export class AuthService {
|
||||||
constructor(private prisma: PrismaService) {}
|
constructor(private prisma: PrismaService) {
|
||||||
|
|
||||||
async login(dto: AuthDto) {
|
|
||||||
const User = await this.prisma.user.findUnique({
|
|
||||||
where: {
|
|
||||||
email: dto.email,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
if (!User) {
|
|
||||||
console.warn(`ACCESS: Refused login for "${dto.email}" (email not used)`);
|
|
||||||
throw new ForbiddenException("Credential(s) invalid.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const pwMatches = await argon.verify(User.hash, dto.password);
|
signin() {
|
||||||
if (!pwMatches) {
|
return {response: "Sign IN"}
|
||||||
console.warn(
|
|
||||||
`ACCESS: Refused login for "${dto.email}" (invalid password)`,
|
|
||||||
);
|
|
||||||
throw new ForbiddenException("Credential(s) invalid.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
delete User.hash;
|
signup() {
|
||||||
console.info(`ACCESS: Granted login for "${dto.email}"`);
|
return {response: "Sign UP"}
|
||||||
return User;
|
|
||||||
}
|
|
||||||
|
|
||||||
async register(dto: AuthDto) {
|
|
||||||
const userPasswordHash = await argon.hash(dto.password);
|
|
||||||
try {
|
|
||||||
const User = await this.prisma.user.create({
|
|
||||||
data: {
|
|
||||||
email: dto.email,
|
|
||||||
hash: userPasswordHash,
|
|
||||||
},
|
|
||||||
select: {
|
|
||||||
id: true,
|
|
||||||
email: true,
|
|
||||||
firstName: true,
|
|
||||||
lastName: true,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
//delete User.hash;
|
|
||||||
return User;
|
|
||||||
} catch (error) {
|
|
||||||
if (error instanceof PrismaClientKnownRequestError) {
|
|
||||||
if (error.code === "P2002") {
|
|
||||||
throw new ForbiddenException("Credential(s) taken.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
@ -1,16 +1,4 @@
|
|||||||
import { IsEmail, IsNotEmpty, IsStrongPassword } from "class-validator";
|
export interface AuthDto {
|
||||||
|
email: string,
|
||||||
export class AuthDto {
|
password: string
|
||||||
@IsEmail()
|
|
||||||
@IsNotEmpty()
|
|
||||||
email: string;
|
|
||||||
|
|
||||||
@IsStrongPassword({
|
|
||||||
minLength: 8,
|
|
||||||
minLowercase: 1,
|
|
||||||
minUppercase: 1,
|
|
||||||
minNumbers: 1,
|
|
||||||
minSymbols: 1,
|
|
||||||
})
|
|
||||||
password: string;
|
|
||||||
}
|
}
|
@ -1,14 +1,8 @@
|
|||||||
import { NestFactory } from '@nestjs/core';
|
import { NestFactory } from '@nestjs/core';
|
||||||
import { AppModule } from './app.module';
|
import { AppModule } from './app.module';
|
||||||
import { ValidationPipe } from "@nestjs/common";
|
|
||||||
|
|
||||||
async function bootstrap() {
|
async function bootstrap() {
|
||||||
const app = await NestFactory.create(AppModule);
|
const app = await NestFactory.create(AppModule);
|
||||||
app.useGlobalPipes(
|
|
||||||
new ValidationPipe({
|
|
||||||
whitelist: true,
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
await app.listen(3333);
|
await app.listen(3333);
|
||||||
}
|
}
|
||||||
bootstrap();
|
bootstrap();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user