137 lines
4.4 KiB
TypeScript
137 lines
4.4 KiB
TypeScript
import {Model, Connection} from 'mongoose';
|
|
import {Injectable, NotFoundException, BadGatewayException, ConflictException, BadRequestException, HttpException, HttpService} from '@nestjs/common';
|
|
import {InjectConnection} from '@nestjs/mongoose';
|
|
import {Store, StoreRequest, StoreSchema} from './store.schema';
|
|
import {DB_TEST_NAME, DB_NAME, COLLECTION_STORE} from 'src/consts';
|
|
import * as jwt from 'jsonwebtoken';
|
|
|
|
interface Token {
|
|
login: string;
|
|
agent: string;
|
|
iat: number;
|
|
exp: number;
|
|
}
|
|
|
|
const validateModel = async (store: Store) => {
|
|
try {
|
|
await store.validate();
|
|
} catch (e) {
|
|
throw new BadGatewayException(e);
|
|
}
|
|
};
|
|
|
|
@Injectable()
|
|
export class StoreService {
|
|
constructor(
|
|
@InjectConnection(DB_NAME) private dbConnection: Connection,
|
|
@InjectConnection(DB_TEST_NAME) private dbTestConnection: Connection,
|
|
private http: HttpService,
|
|
) {}
|
|
|
|
storeModel(api: string): Model<Store> {
|
|
if (api === DB_TEST_NAME) {
|
|
return this.dbTestConnection.model<Store>(COLLECTION_STORE, StoreSchema);
|
|
}
|
|
return this.dbConnection.model<Store>(COLLECTION_STORE, StoreSchema);
|
|
}
|
|
|
|
async findAll(api: string): Promise<Store[]> {
|
|
return this.storeModel(api).find().exec();
|
|
}
|
|
|
|
async create(api: string, store: StoreRequest, access_token: string): Promise<Store> {
|
|
const searchStore = await this.storeModel(api).findOne({key: store.key});
|
|
|
|
if (searchStore) {
|
|
throw new ConflictException(`Api key "${store.key}" is already taken`);
|
|
}
|
|
|
|
const {login, agent} = jwt.decode(access_token) as Token;
|
|
|
|
const apiPath = 'http://api.auth.vigdorov.ru/users/search/';
|
|
const headers = {
|
|
Authorization: access_token,
|
|
'user-agent': agent
|
|
};
|
|
|
|
try {
|
|
const {data: currentUser} = await this.http.get(`${apiPath}${login}`, {headers}).toPromise();
|
|
await this.http.get(`${apiPath}${store.author}`, {headers}).toPromise();
|
|
const author = currentUser.is_admin ? store.author : login;
|
|
const createdStore = new (this.storeModel(api))({
|
|
...store,
|
|
author,
|
|
});
|
|
|
|
try {
|
|
await validateModel(createdStore);
|
|
} catch (e) {
|
|
if (e?.message?.includes('validation failed')) {
|
|
throw new BadRequestException(e.message);
|
|
}
|
|
throw e;
|
|
}
|
|
|
|
|
|
const savedStore = await createdStore.save();
|
|
if (!Object.keys(savedStore.value).length) {
|
|
await savedStore.updateOne({value: {}});
|
|
}
|
|
return savedStore;
|
|
} catch (e) {
|
|
if (e?.response?.data?.statusCode === 404) {
|
|
throw new NotFoundException(e.response.data.message);
|
|
}
|
|
throw new BadRequestException(e.message);
|
|
}
|
|
}
|
|
|
|
async update(api: string, {author, ...omitProps}: StoreRequest): Promise<Store> {
|
|
const searchStore = await this.findOne(api, omitProps.key);
|
|
|
|
if (searchStore) {
|
|
const store = {
|
|
...omitProps,
|
|
author: searchStore.author,
|
|
};
|
|
const updateStore = new (this.storeModel(api))(store);
|
|
try {
|
|
await validateModel(updateStore);
|
|
} catch (e) {
|
|
if (e?.message?.includes('validation failed')) {
|
|
throw new BadRequestException(e.message);
|
|
}
|
|
throw e;
|
|
}
|
|
|
|
await searchStore.updateOne({
|
|
...store,
|
|
author: searchStore.author,
|
|
});
|
|
|
|
return updateStore;
|
|
}
|
|
|
|
throw new NotFoundException(`Not found api key "${omitProps.key}"`);
|
|
}
|
|
|
|
async findOne(api: string, key: string): Promise<Store> {
|
|
const searchStore = await this.storeModel(api).findOne({key});
|
|
if (!searchStore) {
|
|
throw new NotFoundException(`Not found api key "${key}"`);
|
|
}
|
|
return searchStore;
|
|
}
|
|
|
|
async removeOne(api: string, key: string): Promise<Store> {
|
|
const searchStore = await this.findOne(api, key);
|
|
|
|
if (searchStore) {
|
|
await this.storeModel(api).deleteOne({key});
|
|
|
|
return searchStore;
|
|
}
|
|
|
|
throw new NotFoundException(`Not found api key "${key}"`);
|
|
}
|
|
} |