mirror of
https://github.com/apricote/Listory.git
synced 2026-01-13 21:21:02 +00:00
feat(api): user authentication
This commit is contained in:
parent
f14eda16ac
commit
f253a66f86
41 changed files with 657 additions and 338 deletions
10
src/users/dto/create-or-update.dto.ts
Normal file
10
src/users/dto/create-or-update.dto.ts
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
export class CreateOrUpdateDto {
|
||||
displayName: string;
|
||||
photo?: string;
|
||||
|
||||
spotify: {
|
||||
id: string;
|
||||
accessToken: string;
|
||||
refreshToken: string;
|
||||
};
|
||||
}
|
||||
17
src/users/user.entity.ts
Normal file
17
src/users/user.entity.ts
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
import { Entity, Column, PrimaryGeneratedColumn, OneToOne } from "typeorm";
|
||||
import { SpotifyConnection } from "../sources/spotify/spotify-connection.entity";
|
||||
|
||||
@Entity()
|
||||
export class User {
|
||||
@PrimaryGeneratedColumn("uuid")
|
||||
id: string;
|
||||
|
||||
@Column()
|
||||
displayName: string;
|
||||
|
||||
@Column({ nullable: true })
|
||||
photo?: string;
|
||||
|
||||
@Column(type => SpotifyConnection)
|
||||
spotify: SpotifyConnection;
|
||||
}
|
||||
5
src/users/user.repository.ts
Normal file
5
src/users/user.repository.ts
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
import { EntityRepository, Repository } from "typeorm";
|
||||
import { User } from "./user.entity";
|
||||
|
||||
@EntityRepository(User)
|
||||
export class UserRepository extends Repository<User> {}
|
||||
18
src/users/users.controller.spec.ts
Normal file
18
src/users/users.controller.spec.ts
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { UsersController } from './users.controller';
|
||||
|
||||
describe('Users Controller', () => {
|
||||
let controller: UsersController;
|
||||
|
||||
beforeEach(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
controllers: [UsersController],
|
||||
}).compile();
|
||||
|
||||
controller = module.get<UsersController>(UsersController);
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(controller).toBeDefined();
|
||||
});
|
||||
});
|
||||
17
src/users/users.controller.ts
Normal file
17
src/users/users.controller.ts
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
import { Controller, Get } from "@nestjs/common";
|
||||
import { Auth } from "../auth/decorators/auth.decorator";
|
||||
import { ReqUser } from "../auth/decorators/req-user.decorator";
|
||||
import { User } from "./user.entity";
|
||||
|
||||
@Controller("api/v1/users")
|
||||
export class UsersController {
|
||||
@Get("me")
|
||||
@Auth()
|
||||
getMe(@ReqUser() user: User): Omit<User, "spotify"> {
|
||||
return {
|
||||
id: user.id,
|
||||
displayName: user.displayName,
|
||||
photo: user.photo
|
||||
};
|
||||
}
|
||||
}
|
||||
13
src/users/users.module.ts
Normal file
13
src/users/users.module.ts
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
import { Module } from "@nestjs/common";
|
||||
import { TypeOrmModule } from "@nestjs/typeorm";
|
||||
import { UserRepository } from "./user.repository";
|
||||
import { UsersService } from "./users.service";
|
||||
import { UsersController } from './users.controller';
|
||||
|
||||
@Module({
|
||||
imports: [TypeOrmModule.forFeature([UserRepository])],
|
||||
providers: [UsersService],
|
||||
exports: [UsersService],
|
||||
controllers: [UsersController]
|
||||
})
|
||||
export class UsersModule {}
|
||||
18
src/users/users.service.spec.ts
Normal file
18
src/users/users.service.spec.ts
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
import { Test, TestingModule } from "@nestjs/testing";
|
||||
import { UsersService } from "./users.service";
|
||||
|
||||
describe("UsersService", () => {
|
||||
let service: UsersService;
|
||||
|
||||
beforeEach(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
providers: [UsersService]
|
||||
}).compile();
|
||||
|
||||
service = module.get<UsersService>(UsersService);
|
||||
});
|
||||
|
||||
it("should be defined", () => {
|
||||
expect(service).toBeDefined();
|
||||
});
|
||||
});
|
||||
42
src/users/users.service.ts
Normal file
42
src/users/users.service.ts
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
import { Injectable, NotFoundException } from "@nestjs/common";
|
||||
import { CreateOrUpdateDto } from "./dto/create-or-update.dto";
|
||||
import { User } from "./user.entity";
|
||||
import { UserRepository } from "./user.repository";
|
||||
|
||||
@Injectable()
|
||||
export class UsersService {
|
||||
constructor(private readonly userRepository: UserRepository) {}
|
||||
|
||||
async findById(id: string): Promise<User> {
|
||||
const user = await this.userRepository.findOne(id);
|
||||
|
||||
if (!user) {
|
||||
throw new NotFoundException("UserNotFound");
|
||||
}
|
||||
|
||||
return user;
|
||||
}
|
||||
|
||||
async createOrUpdate(data: CreateOrUpdateDto): Promise<User> {
|
||||
let user = await this.userRepository.findOne({
|
||||
where: { spotify: { id: data.spotify.id } }
|
||||
});
|
||||
|
||||
if (!user) {
|
||||
user = this.userRepository.create({
|
||||
spotify: {
|
||||
id: data.spotify.id
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
user.spotify.accessToken = data.spotify.accessToken;
|
||||
user.spotify.refreshToken = data.spotify.refreshToken;
|
||||
user.displayName = data.displayName;
|
||||
user.photo = data.photo;
|
||||
|
||||
await this.userRepository.save(user);
|
||||
|
||||
return user;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue