final
This commit is contained in:
57
.http
Normal file
57
.http
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
### use REST Client plugin for VSCode https://marketplace.visualstudio.com/items?itemName=humao.rest-client
|
||||||
|
@host = http://localhost:4005
|
||||||
|
@user = test_user
|
||||||
|
@auth = 7b5da8a1-b64c-43ea-90f3-cdd3da507504
|
||||||
|
@storage_id = 67c420ab38fafe445411e76a
|
||||||
|
|
||||||
|
### Auth
|
||||||
|
POST {{host}}/auth HTTP/1.1
|
||||||
|
content-type: application/json
|
||||||
|
|
||||||
|
{
|
||||||
|
"login": "{{user}}"
|
||||||
|
}
|
||||||
|
|
||||||
|
### Get storages list
|
||||||
|
GET {{host}}/storages HTTP/1.1
|
||||||
|
content-type: application/json
|
||||||
|
Authorization: {{auth}}
|
||||||
|
|
||||||
|
{
|
||||||
|
"login": "test_user"
|
||||||
|
}
|
||||||
|
|
||||||
|
### Create storage
|
||||||
|
POST {{host}}/storages HTTP/1.1
|
||||||
|
content-type: application/json
|
||||||
|
Authorization: {{auth}}
|
||||||
|
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"users": ["ivan", "maria"],
|
||||||
|
"count": 2
|
||||||
|
},
|
||||||
|
"storageName": "users"
|
||||||
|
}
|
||||||
|
|
||||||
|
### Get storage
|
||||||
|
GET {{host}}/storages/{{storage_id}} HTTP/1.1
|
||||||
|
content-type: application/json
|
||||||
|
Authorization: {{auth}}
|
||||||
|
|
||||||
|
### Update storage
|
||||||
|
PUT {{host}}/storages/{{storage_id}} HTTP/1.1
|
||||||
|
content-type: application/json
|
||||||
|
Authorization: {{auth}}
|
||||||
|
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"users": ["ivan", "maria", "fedor"],
|
||||||
|
"count": 3
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
### Remove image
|
||||||
|
DELETE {{host}}/storages/{{storage_id}} HTTP/1.1
|
||||||
|
content-type: application/json
|
||||||
|
Authorization: {{auth}}
|
||||||
@ -16,7 +16,13 @@ export const AUTH_ERROR: ApiResponseOptions = {
|
|||||||
|
|
||||||
export const GET_STORAGES_LIST_SUCCESS: ApiResponseOptions = {
|
export const GET_STORAGES_LIST_SUCCESS: ApiResponseOptions = {
|
||||||
status: 200,
|
status: 200,
|
||||||
description: 'Список всех картинок',
|
description: 'Список всех storage пользователя',
|
||||||
type: StorageResponse,
|
type: StorageResponse,
|
||||||
isArray: true,
|
isArray: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const MANIPULATE_STORAGE_SUCCESS: ApiResponseOptions = {
|
||||||
|
status: 200,
|
||||||
|
description: 'Storage',
|
||||||
|
type: StorageResponse,
|
||||||
|
};
|
||||||
|
|||||||
@ -1,15 +1,24 @@
|
|||||||
import {
|
import {
|
||||||
Controller,
|
Controller,
|
||||||
|
Delete,
|
||||||
Get,
|
Get,
|
||||||
Header,
|
Header,
|
||||||
HttpCode,
|
HttpCode,
|
||||||
Options,
|
Options,
|
||||||
Post,
|
Post,
|
||||||
|
Put,
|
||||||
Req,
|
Req,
|
||||||
} from '@nestjs/common';
|
} from '@nestjs/common';
|
||||||
import { Request } from 'express';
|
import { Request } from 'express';
|
||||||
import { AppService } from './app.service';
|
import { AppService } from './app.service';
|
||||||
import { ApiBody, ApiResponse, ApiSecurity, ApiTags } from '@nestjs/swagger';
|
import {
|
||||||
|
ApiBody,
|
||||||
|
ApiExcludeEndpoint,
|
||||||
|
ApiParam,
|
||||||
|
ApiResponse,
|
||||||
|
ApiSecurity,
|
||||||
|
ApiTags,
|
||||||
|
} from '@nestjs/swagger';
|
||||||
import {
|
import {
|
||||||
ALLOW_CREDENTIALS,
|
ALLOW_CREDENTIALS,
|
||||||
ALLOW_HEADERS,
|
ALLOW_HEADERS,
|
||||||
@ -20,10 +29,11 @@ import {
|
|||||||
import {
|
import {
|
||||||
AUTH_ERROR,
|
AUTH_ERROR,
|
||||||
AUTH_SUCCESS,
|
AUTH_SUCCESS,
|
||||||
|
MANIPULATE_STORAGE_SUCCESS,
|
||||||
GET_STORAGES_LIST_SUCCESS,
|
GET_STORAGES_LIST_SUCCESS,
|
||||||
} from './api.responses';
|
} from './api.responses';
|
||||||
import { AuthRequest } from './schemas';
|
import { AuthRequest, StorageCreateRequest } from './schemas';
|
||||||
import { Storage } from './types';
|
import { Storage, StorageCreate, StorageList, StorageUpdate } from './types';
|
||||||
|
|
||||||
@Controller()
|
@Controller()
|
||||||
@ApiTags('storage-app')
|
@ApiTags('storage-app')
|
||||||
@ -48,14 +58,89 @@ export class AppController {
|
|||||||
@Header(...ALLOW_ORIGIN_ALL)
|
@Header(...ALLOW_ORIGIN_ALL)
|
||||||
@ApiResponse(GET_STORAGES_LIST_SUCCESS)
|
@ApiResponse(GET_STORAGES_LIST_SUCCESS)
|
||||||
@ApiResponse(AUTH_ERROR)
|
@ApiResponse(AUTH_ERROR)
|
||||||
async getStorageList(@Req() request: Request): Promise<Storage[]> {
|
async getStorageList(@Req() request: Request): Promise<StorageList> {
|
||||||
const { login } = await this.appService.checkRequest(
|
const { login } = await this.appService.checkRequest(
|
||||||
request.headers.authorization,
|
request.headers.authorization,
|
||||||
);
|
);
|
||||||
return this.appService.getStorageList(login);
|
return this.appService.getStorageList(login);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Options(['', '/auth'])
|
@Get('/storages/:id')
|
||||||
|
@ApiSecurity('apiKey')
|
||||||
|
@ApiParam({
|
||||||
|
name: 'id',
|
||||||
|
description: 'id storage',
|
||||||
|
})
|
||||||
|
@Header(...ALLOW_ORIGIN_ALL)
|
||||||
|
@ApiResponse(MANIPULATE_STORAGE_SUCCESS)
|
||||||
|
@ApiResponse(AUTH_ERROR)
|
||||||
|
async getImageById(
|
||||||
|
@Req() request: Request<{ id: string }>,
|
||||||
|
): Promise<Storage> {
|
||||||
|
const { login } = await this.appService.checkRequest(
|
||||||
|
request.headers.authorization,
|
||||||
|
);
|
||||||
|
return this.appService.getStorageById(login, request.params.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Post('/storages')
|
||||||
|
@ApiSecurity('apiKey')
|
||||||
|
@ApiBody({
|
||||||
|
type: StorageCreateRequest,
|
||||||
|
description: 'Объект создания storage',
|
||||||
|
})
|
||||||
|
@Header(...ALLOW_ORIGIN_ALL)
|
||||||
|
@ApiResponse(MANIPULATE_STORAGE_SUCCESS)
|
||||||
|
@ApiResponse(AUTH_ERROR)
|
||||||
|
async createImage(
|
||||||
|
@Req() request: Request<null, null, StorageCreate>,
|
||||||
|
): Promise<Storage> {
|
||||||
|
const { login } = await this.appService.checkRequest(
|
||||||
|
request.headers.authorization,
|
||||||
|
);
|
||||||
|
return this.appService.addStorage(login, request.body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Put('/storages/:id')
|
||||||
|
@ApiSecurity('apiKey')
|
||||||
|
@ApiParam({
|
||||||
|
name: 'id',
|
||||||
|
description: 'id storage',
|
||||||
|
})
|
||||||
|
@Header(...ALLOW_ORIGIN_ALL)
|
||||||
|
@ApiResponse(MANIPULATE_STORAGE_SUCCESS)
|
||||||
|
@ApiResponse(AUTH_ERROR)
|
||||||
|
async toggleLike(
|
||||||
|
@Req() request: Request<{ id: string }, null, StorageUpdate>,
|
||||||
|
): Promise<Storage> {
|
||||||
|
const { login } = await this.appService.checkRequest(
|
||||||
|
request.headers.authorization,
|
||||||
|
);
|
||||||
|
return this.appService.updateStorage(
|
||||||
|
login,
|
||||||
|
request.params.id,
|
||||||
|
request.body,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Delete('/storages/:id')
|
||||||
|
@ApiSecurity('apiKey')
|
||||||
|
@ApiParam({
|
||||||
|
name: 'id',
|
||||||
|
description: 'id картинки',
|
||||||
|
})
|
||||||
|
@Header(...ALLOW_ORIGIN_ALL)
|
||||||
|
@ApiResponse(MANIPULATE_STORAGE_SUCCESS)
|
||||||
|
@ApiResponse(AUTH_ERROR)
|
||||||
|
async deleteImage(@Req() request: Request<{ id: string }>): Promise<Storage> {
|
||||||
|
const { login } = await this.appService.checkRequest(
|
||||||
|
request.headers.authorization,
|
||||||
|
);
|
||||||
|
return this.appService.deleteStorageById(login, request.params.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiExcludeEndpoint()
|
||||||
|
@Options(['', '/auth', '/storages', '/storages/:id'])
|
||||||
@Header(...ALLOW_ORIGIN_ALL)
|
@Header(...ALLOW_ORIGIN_ALL)
|
||||||
@Header(...ALLOW_METHOD)
|
@Header(...ALLOW_METHOD)
|
||||||
@Header(...ALLOW_CREDENTIALS)
|
@Header(...ALLOW_CREDENTIALS)
|
||||||
|
|||||||
@ -6,7 +6,13 @@ import {
|
|||||||
import { InjectModel } from '@nestjs/mongoose';
|
import { InjectModel } from '@nestjs/mongoose';
|
||||||
import { StorageDocument, UserDocument } from './schemas';
|
import { StorageDocument, UserDocument } from './schemas';
|
||||||
import { Model } from 'mongoose';
|
import { Model } from 'mongoose';
|
||||||
import { User, Storage, StorageCreate, StorageUpdate } from './types';
|
import {
|
||||||
|
User,
|
||||||
|
Storage,
|
||||||
|
StorageCreate,
|
||||||
|
StorageUpdate,
|
||||||
|
StorageList,
|
||||||
|
} from './types';
|
||||||
import { v4 } from 'uuid';
|
import { v4 } from 'uuid';
|
||||||
import { DB_STORAGES, DB_USERS } from './consts';
|
import { DB_STORAGES, DB_USERS } from './consts';
|
||||||
|
|
||||||
@ -46,12 +52,12 @@ export class AppService {
|
|||||||
return newUser.token;
|
return newUser.token;
|
||||||
}
|
}
|
||||||
|
|
||||||
async getStorageList(login: string): Promise<Storage[]> {
|
async getStorageList(login: string): Promise<StorageList> {
|
||||||
const storageList = await this.storageModel.find().exec();
|
const storageList = await this.storageModel.find().exec();
|
||||||
const preparedList = storageList.map(({ data, _id, user }) => ({
|
const preparedList = storageList.map(({ _id, user, storageName }) => ({
|
||||||
data,
|
|
||||||
id: _id as string,
|
id: _id as string,
|
||||||
user,
|
user,
|
||||||
|
storageName,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
return preparedList.filter(({ user }) => user === login);
|
return preparedList.filter(({ user }) => user === login);
|
||||||
@ -63,6 +69,7 @@ export class AppService {
|
|||||||
return {
|
return {
|
||||||
data: searchStorage.data,
|
data: searchStorage.data,
|
||||||
id: searchStorage._id as string,
|
id: searchStorage._id as string,
|
||||||
|
storageName: searchStorage.storageName,
|
||||||
user: searchStorage.user,
|
user: searchStorage.user,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -73,6 +80,7 @@ export class AppService {
|
|||||||
const Model = this.storageModel;
|
const Model = this.storageModel;
|
||||||
const storageModel = new Model({
|
const storageModel = new Model({
|
||||||
data: storage.data,
|
data: storage.data,
|
||||||
|
storageName: storage.storageName,
|
||||||
user: login,
|
user: login,
|
||||||
});
|
});
|
||||||
try {
|
try {
|
||||||
@ -86,6 +94,7 @@ export class AppService {
|
|||||||
return {
|
return {
|
||||||
data: newStorage.data,
|
data: newStorage.data,
|
||||||
user: newStorage.user,
|
user: newStorage.user,
|
||||||
|
storageName: newStorage.storageName,
|
||||||
id: newStorage._id as string,
|
id: newStorage._id as string,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -101,13 +110,17 @@ export class AppService {
|
|||||||
throw new BadRequestException(`Storage с id - "${id}" не найден`);
|
throw new BadRequestException(`Storage с id - "${id}" не найден`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const updatedStorageName = storage.storageName ?? searchStorage.storageName;
|
||||||
|
|
||||||
await searchStorage.updateOne({
|
await searchStorage.updateOne({
|
||||||
data: storage.data,
|
data: storage.data,
|
||||||
|
storageName: updatedStorageName,
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
data: storage.data,
|
data: storage.data,
|
||||||
user: searchStorage.user,
|
user: searchStorage.user,
|
||||||
|
storageName: updatedStorageName,
|
||||||
id: searchStorage._id as string,
|
id: searchStorage._id as string,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -124,6 +137,7 @@ export class AppService {
|
|||||||
return {
|
return {
|
||||||
data: searchStorage.data,
|
data: searchStorage.data,
|
||||||
user: searchStorage.user,
|
user: searchStorage.user,
|
||||||
|
storageName: searchStorage.storageName,
|
||||||
id: searchStorage._id as string,
|
id: searchStorage._id as string,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,7 +22,7 @@ async function bootstrap() {
|
|||||||
|
|
||||||
SwaggerModule.setup('api', app, document);
|
SwaggerModule.setup('api', app, document);
|
||||||
|
|
||||||
await app.listen(process.env.PORT ?? 3000);
|
await app.listen(4005);
|
||||||
}
|
}
|
||||||
|
|
||||||
void bootstrap();
|
void bootstrap();
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
|
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
|
||||||
import { ApiProperty } from '@nestjs/swagger';
|
import { ApiProperty } from '@nestjs/swagger';
|
||||||
import { Document } from 'mongoose';
|
import { Document } from 'mongoose';
|
||||||
import { Storage } from './types';
|
import { Storage, StorageCreate } from './types';
|
||||||
|
|
||||||
export class AuthRequest {
|
export class AuthRequest {
|
||||||
@ApiProperty()
|
@ApiProperty()
|
||||||
@ -31,6 +31,12 @@ export class StorageDocument extends Document {
|
|||||||
})
|
})
|
||||||
data: object;
|
data: object;
|
||||||
|
|
||||||
|
@Prop({
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
})
|
||||||
|
storageName: string;
|
||||||
|
|
||||||
@Prop({
|
@Prop({
|
||||||
type: String,
|
type: String,
|
||||||
required: true,
|
required: true,
|
||||||
@ -48,6 +54,17 @@ export class StorageResponse implements Storage {
|
|||||||
@ApiProperty()
|
@ApiProperty()
|
||||||
user: string;
|
user: string;
|
||||||
|
|
||||||
|
@ApiProperty()
|
||||||
|
storageName: string;
|
||||||
|
|
||||||
@ApiProperty()
|
@ApiProperty()
|
||||||
id: string;
|
id: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class StorageCreateRequest implements StorageCreate {
|
||||||
|
@ApiProperty()
|
||||||
|
data: object;
|
||||||
|
|
||||||
|
@ApiProperty()
|
||||||
|
storageName: string;
|
||||||
|
}
|
||||||
|
|||||||
@ -5,14 +5,23 @@ export type User = {
|
|||||||
|
|
||||||
export type Storage = {
|
export type Storage = {
|
||||||
data: object;
|
data: object;
|
||||||
|
storageName: string;
|
||||||
user: string;
|
user: string;
|
||||||
id: string;
|
id: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type StorageList = Array<{
|
||||||
|
user: string;
|
||||||
|
storageName: string;
|
||||||
|
id: string;
|
||||||
|
}>;
|
||||||
|
|
||||||
export type StorageCreate = {
|
export type StorageCreate = {
|
||||||
data: object;
|
data: object;
|
||||||
|
storageName: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type StorageUpdate = {
|
export type StorageUpdate = {
|
||||||
data: object;
|
data: object;
|
||||||
|
storageName?: string;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user