Compare commits
13 Commits
ac00667465
...
v0.0.11
| Author | SHA1 | Date | |
|---|---|---|---|
| b3ce56c605 | |||
| 28cefa792c | |||
| 0803abc168 | |||
| 02ae883fa4 | |||
| be4050768e | |||
| dc6ec23cb9 | |||
| 1bb98c13d1 | |||
| bca979bab5 | |||
| e4fafd764c | |||
| 172159414b | |||
| 9355138a8c | |||
| 343cd8b772 | |||
| 01e0d5b94d |
47
package.json
47
package.json
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@odit/lfk-backend",
|
"name": "@odit/lfk-backend",
|
||||||
"version": "0.0.10",
|
"version": "0.0.11",
|
||||||
"main": "src/app.ts",
|
"main": "src/app.ts",
|
||||||
"repository": "https://git.odit.services/lfk/backend",
|
"repository": "https://git.odit.services/lfk/backend",
|
||||||
"author": {
|
"author": {
|
||||||
@@ -22,11 +22,11 @@
|
|||||||
],
|
],
|
||||||
"license": "CC-BY-NC-SA-4.0",
|
"license": "CC-BY-NC-SA-4.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"argon2": "^0.27.0",
|
"argon2": "^0.27.1",
|
||||||
"body-parser": "^1.19.0",
|
"body-parser": "^1.19.0",
|
||||||
"class-transformer": "^0.3.1",
|
"class-transformer": "^0.3.1",
|
||||||
"class-validator": "^0.12.2",
|
"class-validator": "^0.12.2",
|
||||||
"class-validator-jsonschema": "^2.0.3",
|
"class-validator-jsonschema": "^2.1.0",
|
||||||
"consola": "^2.15.0",
|
"consola": "^2.15.0",
|
||||||
"cookie": "^0.4.1",
|
"cookie": "^0.4.1",
|
||||||
"cookie-parser": "^1.4.5",
|
"cookie-parser": "^1.4.5",
|
||||||
@@ -39,33 +39,34 @@
|
|||||||
"pg": "^8.5.1",
|
"pg": "^8.5.1",
|
||||||
"reflect-metadata": "^0.1.13",
|
"reflect-metadata": "^0.1.13",
|
||||||
"routing-controllers": "^0.9.0-alpha.6",
|
"routing-controllers": "^0.9.0-alpha.6",
|
||||||
"routing-controllers-openapi": "^2.1.0",
|
"routing-controllers-openapi": "^2.2.0",
|
||||||
"sqlite3": "5.0.0",
|
"sqlite3": "5.0.0",
|
||||||
"typeorm": "^0.2.29",
|
"typeorm": "^0.2.29",
|
||||||
"typeorm-routing-controllers-extensions": "^0.2.0",
|
"typeorm-routing-controllers-extensions": "^0.2.0",
|
||||||
"typeorm-seeding": "^1.6.1",
|
"typeorm-seeding": "^1.6.1",
|
||||||
"uuid": "^8.3.1",
|
"uuid": "^8.3.2",
|
||||||
"validator": "^13.5.2"
|
"validator": "^13.5.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@odit/license-exporter": "^0.0.8",
|
"@odit/license-exporter": "^0.0.9",
|
||||||
"@types/cors": "^2.8.8",
|
"@types/cors": "^2.8.9",
|
||||||
"@types/csvtojson": "^1.1.5",
|
"@types/csvtojson": "^1.1.5",
|
||||||
"@types/express": "^4.17.9",
|
"@types/express": "^4.17.9",
|
||||||
"@types/jest": "^26.0.16",
|
"@types/jest": "^26.0.16",
|
||||||
"@types/jsonwebtoken": "^8.5.0",
|
"@types/jsonwebtoken": "^8.5.0",
|
||||||
"@types/node": "^14.14.9",
|
"@types/node": "^14.14.20",
|
||||||
"@types/uuid": "^8.3.0",
|
"@types/uuid": "^8.3.0",
|
||||||
"axios": "^0.21.0",
|
"axios": "^0.21.1",
|
||||||
"cp-cli": "^2.0.0",
|
"cp-cli": "^2.0.0",
|
||||||
"jest": "^26.6.3",
|
"jest": "^26.6.3",
|
||||||
"nodemon": "^2.0.6",
|
"nodemon": "^2.0.7",
|
||||||
"rimraf": "^2.7.1",
|
"release-it": "^14.2.2",
|
||||||
"start-server-and-test": "^1.11.6",
|
"rimraf": "^3.0.2",
|
||||||
|
"start-server-and-test": "^1.11.7",
|
||||||
"ts-jest": "^26.4.4",
|
"ts-jest": "^26.4.4",
|
||||||
"ts-node": "^9.0.0",
|
"ts-node": "^9.1.1",
|
||||||
"typedoc": "^0.19.2",
|
"typedoc": "^0.20.14",
|
||||||
"typescript": "^4.1.2"
|
"typescript": "^4.1.3"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "nodemon src/app.ts",
|
"dev": "nodemon src/app.ts",
|
||||||
@@ -76,7 +77,21 @@
|
|||||||
"test:ci": "start-server-and-test dev http://localhost:4010/api/docs/openapi.json test",
|
"test:ci": "start-server-and-test dev http://localhost:4010/api/docs/openapi.json test",
|
||||||
"seed": "ts-node ./node_modules/typeorm/cli.js schema:sync && ts-node ./node_modules/typeorm-seeding/dist/cli.js seed",
|
"seed": "ts-node ./node_modules/typeorm/cli.js schema:sync && ts-node ./node_modules/typeorm-seeding/dist/cli.js seed",
|
||||||
"openapi:export": "ts-node scripts/openapi_export.ts",
|
"openapi:export": "ts-node scripts/openapi_export.ts",
|
||||||
"licenses:export": "license-exporter --md"
|
"licenses:export": "license-exporter --md",
|
||||||
|
"release": "release-it"
|
||||||
|
},
|
||||||
|
"release-it": {
|
||||||
|
"git": {
|
||||||
|
"requireCleanWorkingDir": false,
|
||||||
|
"requireBranch": "main",
|
||||||
|
"push": false,
|
||||||
|
"tag": true,
|
||||||
|
"tagName": "v${version}",
|
||||||
|
"tagAnnotation": "v${version}"
|
||||||
|
},
|
||||||
|
"npm": {
|
||||||
|
"publish": false
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"nodemonConfig": {
|
"nodemonConfig": {
|
||||||
"ignore": [
|
"ignore": [
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import consola from "consola";
|
|||||||
import fs from "fs";
|
import fs from "fs";
|
||||||
import "reflect-metadata";
|
import "reflect-metadata";
|
||||||
import { createExpressServer, getMetadataArgsStorage } from "routing-controllers";
|
import { createExpressServer, getMetadataArgsStorage } from "routing-controllers";
|
||||||
import { routingControllersToSpec } from 'routing-controllers-openapi';
|
import { generateSpec } from '../src/apispec';
|
||||||
import { config } from '../src/config';
|
import { config } from '../src/config';
|
||||||
import authchecker from "../src/middlewares/authchecker";
|
import authchecker from "../src/middlewares/authchecker";
|
||||||
import { ErrorHandler } from '../src/middlewares/ErrorHandler';
|
import { ErrorHandler } from '../src/middlewares/ErrorHandler';
|
||||||
@@ -24,46 +24,7 @@ const schemas = validationMetadatasToSchemas({
|
|||||||
});
|
});
|
||||||
|
|
||||||
//Spec creation based on the previously created schemas
|
//Spec creation based on the previously created schemas
|
||||||
const spec = routingControllersToSpec(
|
const spec = generateSpec(storage, schemas);
|
||||||
storage,
|
|
||||||
{
|
|
||||||
routePrefix: "/api"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
components: {
|
|
||||||
schemas,
|
|
||||||
"securitySchemes": {
|
|
||||||
"AuthToken": {
|
|
||||||
"type": "http",
|
|
||||||
"scheme": "bearer",
|
|
||||||
"bearerFormat": "JWT",
|
|
||||||
description: "A JWT based access token. Use /api/auth/login or /api/auth/refresh to get one."
|
|
||||||
},
|
|
||||||
"RefreshTokenCookie": {
|
|
||||||
"type": "apiKey",
|
|
||||||
"in": "cookie",
|
|
||||||
"name": "lfk_backend__refresh_token",
|
|
||||||
description: "A cookie containing a JWT based refreh token. Attention: Doesn't work in swagger-ui. Use /api/auth/login or /api/auth/refresh to get one."
|
|
||||||
},
|
|
||||||
"StatsApiToken": {
|
|
||||||
"type": "http",
|
|
||||||
"scheme": "bearer",
|
|
||||||
description: "Api token that can be obtained by creating a new stats client (post to /api/statsclients). Only valid for obtaining stats."
|
|
||||||
},
|
|
||||||
"StationApiToken": {
|
|
||||||
"type": "http",
|
|
||||||
"scheme": "bearer",
|
|
||||||
description: "Api token that can be obtained by creating a new scan station (post to /api/stations). Only valid for creating scans."
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
info: {
|
|
||||||
description: "The the backend API for the LfK! runner system.",
|
|
||||||
title: "LfK! Backend API",
|
|
||||||
version: "0.0.8",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
fs.writeFileSync("./openapi.json", JSON.stringify(spec), { encoding: "utf-8" });
|
fs.writeFileSync("./openapi.json", JSON.stringify(spec), { encoding: "utf-8" });
|
||||||
|
|||||||
50
src/apispec.ts
Normal file
50
src/apispec.ts
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
import { MetadataArgsStorage } from 'routing-controllers';
|
||||||
|
import { routingControllersToSpec } from 'routing-controllers-openapi';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function generates a the openapi spec from route metadata and type schemas.
|
||||||
|
* @param storage MetadataArgsStorage object generated by routing-controllers.
|
||||||
|
* @param schemas MetadataArgsStorage object generated by class-validator-jsonschema.
|
||||||
|
*/
|
||||||
|
export function generateSpec(storage: MetadataArgsStorage, schemas) {
|
||||||
|
return routingControllersToSpec(
|
||||||
|
storage,
|
||||||
|
{
|
||||||
|
routePrefix: "/api"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
components: {
|
||||||
|
schemas,
|
||||||
|
"securitySchemes": {
|
||||||
|
"AuthToken": {
|
||||||
|
"type": "http",
|
||||||
|
"scheme": "bearer",
|
||||||
|
"bearerFormat": "JWT",
|
||||||
|
description: "A JWT based access token. Use /api/auth/login or /api/auth/refresh to get one."
|
||||||
|
},
|
||||||
|
"RefreshTokenCookie": {
|
||||||
|
"type": "apiKey",
|
||||||
|
"in": "cookie",
|
||||||
|
"name": "lfk_backend__refresh_token",
|
||||||
|
description: "A cookie containing a JWT based refreh token. Attention: Doesn't work in swagger-ui. Use /api/auth/login or /api/auth/refresh to get one."
|
||||||
|
},
|
||||||
|
"StatsApiToken": {
|
||||||
|
"type": "http",
|
||||||
|
"scheme": "bearer",
|
||||||
|
description: "Api token that can be obtained by creating a new stats client (post to /api/statsclients). Only valid for obtaining stats."
|
||||||
|
},
|
||||||
|
"StationApiToken": {
|
||||||
|
"type": "http",
|
||||||
|
"scheme": "bearer",
|
||||||
|
description: "Api token that can be obtained by creating a new scan station (post to /api/stations). Only valid for creating scans."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
info: {
|
||||||
|
description: "The the backend API for the LfK! runner system.",
|
||||||
|
title: "LfK! Backend API",
|
||||||
|
version: process.env.npm_package_version
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Authorized, Body, Delete, Get, JsonController, OnUndefined, Param, Post } from 'routing-controllers';
|
import { Authorized, Body, Delete, Get, JsonController, OnUndefined, Param, Post, QueryParam } from 'routing-controllers';
|
||||||
import { OpenAPI, ResponseSchema } from 'routing-controllers-openapi';
|
import { OpenAPI, ResponseSchema } from 'routing-controllers-openapi';
|
||||||
import { getConnectionManager, Repository } from 'typeorm';
|
import { getConnectionManager, Repository } from 'typeorm';
|
||||||
import { StatsClientNotFoundError } from '../errors/StatsClientErrors';
|
import { StatsClientNotFoundError } from '../errors/StatsClientErrors';
|
||||||
@@ -65,7 +65,7 @@ export class StatsClientController {
|
|||||||
@ResponseSchema(ResponseEmpty, { statusCode: 204 })
|
@ResponseSchema(ResponseEmpty, { statusCode: 204 })
|
||||||
@OnUndefined(204)
|
@OnUndefined(204)
|
||||||
@OpenAPI({ description: "Delete the stats client whose id you provided. <br> If no client with this id exists it will just return 204(no content)." })
|
@OpenAPI({ description: "Delete the stats client whose id you provided. <br> If no client with this id exists it will just return 204(no content)." })
|
||||||
async remove(@Param("id") id: number) {
|
async remove(@Param("id") id: number, @QueryParam("force") force: boolean) {
|
||||||
let client = await this.clientRepository.findOne({ id: id });
|
let client = await this.clientRepository.findOne({ id: id });
|
||||||
if (!client) { return null; }
|
if (!client) { return null; }
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { getConnectionManager, Repository } from 'typeorm';
|
|||||||
import { EntityFromBody } from 'typeorm-routing-controllers-extensions';
|
import { EntityFromBody } from 'typeorm-routing-controllers-extensions';
|
||||||
import { UserGroupIdsNotMatchingError, UserGroupNotFoundError } from '../errors/UserGroupErrors';
|
import { UserGroupIdsNotMatchingError, UserGroupNotFoundError } from '../errors/UserGroupErrors';
|
||||||
import { CreateUserGroup } from '../models/actions/create/CreateUserGroup';
|
import { CreateUserGroup } from '../models/actions/create/CreateUserGroup';
|
||||||
|
import { UpdateUserGroup } from '../models/actions/update/UpdateUserGroup';
|
||||||
import { UserGroup } from '../models/entities/UserGroup';
|
import { UserGroup } from '../models/entities/UserGroup';
|
||||||
import { ResponseEmpty } from '../models/responses/ResponseEmpty';
|
import { ResponseEmpty } from '../models/responses/ResponseEmpty';
|
||||||
import { ResponseUserGroup } from '../models/responses/ResponseUserGroup';
|
import { ResponseUserGroup } from '../models/responses/ResponseUserGroup';
|
||||||
@@ -62,19 +63,19 @@ export class UserGroupController {
|
|||||||
@ResponseSchema(UserGroupNotFoundError, { statusCode: 404 })
|
@ResponseSchema(UserGroupNotFoundError, { statusCode: 404 })
|
||||||
@ResponseSchema(UserGroupIdsNotMatchingError, { statusCode: 406 })
|
@ResponseSchema(UserGroupIdsNotMatchingError, { statusCode: 406 })
|
||||||
@OpenAPI({ description: "Update the group whose id you provided. <br> To change the permissions granted to the group please use /api/permissions instead. <br> Please remember that ids can't be changed." })
|
@OpenAPI({ description: "Update the group whose id you provided. <br> To change the permissions granted to the group please use /api/permissions instead. <br> Please remember that ids can't be changed." })
|
||||||
async put(@Param('id') id: number, @EntityFromBody() userGroup: UserGroup) {
|
async put(@Param('id') id: number, @EntityFromBody() updateGroup: UpdateUserGroup) {
|
||||||
let oldUserGroup = await this.userGroupsRepository.findOne({ id: id }, { relations: ["permissions"] });
|
let oldGroup = await this.userGroupsRepository.findOne({ id: id });
|
||||||
|
|
||||||
if (!oldUserGroup) {
|
if (!oldGroup) {
|
||||||
throw new UserGroupNotFoundError()
|
throw new UserGroupNotFoundError();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (oldUserGroup.id != userGroup.id) {
|
if (oldGroup.id != updateGroup.id) {
|
||||||
throw new UserGroupIdsNotMatchingError();
|
throw new UserGroupIdsNotMatchingError();
|
||||||
}
|
}
|
||||||
|
await this.userGroupsRepository.save(await updateGroup.update(oldGroup));
|
||||||
|
|
||||||
await this.userGroupsRepository.save(userGroup);
|
return (await this.userGroupsRepository.findOne({ id: id }, { relations: ['permissions', 'groups'] })).toResponse();
|
||||||
return userGroup;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Delete('/:id')
|
@Delete('/:id')
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { validationMetadatasToSchemas } from "class-validator-jsonschema";
|
|||||||
import express, { Application } from "express";
|
import express, { Application } from "express";
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import { getMetadataArgsStorage } from "routing-controllers";
|
import { getMetadataArgsStorage } from "routing-controllers";
|
||||||
import { routingControllersToSpec } from "routing-controllers-openapi";
|
import { generateSpec } from '../apispec';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loader for everything openapi related - from creating the schema to serving it via a static route and swaggerUiExpress.
|
* Loader for everything openapi related - from creating the schema to serving it via a static route and swaggerUiExpress.
|
||||||
@@ -15,46 +15,7 @@ export default async (app: Application) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
//Spec creation based on the previously created schemas
|
//Spec creation based on the previously created schemas
|
||||||
const spec = routingControllersToSpec(
|
const spec = generateSpec(storage, schemas);
|
||||||
storage,
|
|
||||||
{
|
|
||||||
routePrefix: "/api"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
components: {
|
|
||||||
schemas,
|
|
||||||
"securitySchemes": {
|
|
||||||
"AuthToken": {
|
|
||||||
"type": "http",
|
|
||||||
"scheme": "bearer",
|
|
||||||
"bearerFormat": "JWT",
|
|
||||||
description: "A JWT based access token. Use /api/auth/login or /api/auth/refresh to get one."
|
|
||||||
},
|
|
||||||
"RefreshTokenCookie": {
|
|
||||||
"type": "apiKey",
|
|
||||||
"in": "cookie",
|
|
||||||
"name": "lfk_backend__refresh_token",
|
|
||||||
description: "A cookie containing a JWT based refreh token. Attention: Doesn't work in swagger-ui. Use /api/auth/login or /api/auth/refresh to get one."
|
|
||||||
},
|
|
||||||
"StatsApiToken": {
|
|
||||||
"type": "http",
|
|
||||||
"scheme": "bearer",
|
|
||||||
description: "Api token that can be obtained by creating a new stats client (post to /api/statsclients). Only valid for obtaining stats."
|
|
||||||
},
|
|
||||||
"StationApiToken": {
|
|
||||||
"type": "http",
|
|
||||||
"scheme": "bearer",
|
|
||||||
description: "Api token that can be obtained by creating a new scan station (post to /api/stations). Only valid for creating scans."
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
info: {
|
|
||||||
description: "The the backend API for the LfK! runner system.",
|
|
||||||
title: "LfK! Backend API",
|
|
||||||
version: "0.0.8",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
);
|
|
||||||
app.get(["/api/docs/openapi.json", "/api/docs/swagger.json"], (req, res) => {
|
app.get(["/api/docs/openapi.json", "/api/docs/swagger.json"], (req, res) => {
|
||||||
res.json(spec);
|
res.json(spec);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { config } from '../../config';
|
|||||||
import { IllegalJWTError, JwtNotProvidedError, RefreshTokenCountInvalidError, UserDisabledError, UserNotFoundError } from '../../errors/AuthError';
|
import { IllegalJWTError, JwtNotProvidedError, RefreshTokenCountInvalidError, UserDisabledError, UserNotFoundError } from '../../errors/AuthError';
|
||||||
import { JwtCreator } from "../../jwtcreator";
|
import { JwtCreator } from "../../jwtcreator";
|
||||||
import { User } from '../entities/User';
|
import { User } from '../entities/User';
|
||||||
import { Auth } from '../responses/ResponseAuth';
|
import { ResponseAuth } from '../responses/ResponseAuth';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class is used to create refreshed auth credentials.
|
* This class is used to create refreshed auth credentials.
|
||||||
@@ -24,8 +24,8 @@ export class RefreshAuth {
|
|||||||
/**
|
/**
|
||||||
* Creates a new auth object based on this.
|
* Creates a new auth object based on this.
|
||||||
*/
|
*/
|
||||||
public async toAuth(): Promise<Auth> {
|
public async toAuth(): Promise<ResponseAuth> {
|
||||||
let newAuth: Auth = new Auth();
|
let newAuth: ResponseAuth = new ResponseAuth();
|
||||||
if (!this.token || this.token === undefined) {
|
if (!this.token || this.token === undefined) {
|
||||||
throw new JwtNotProvidedError()
|
throw new JwtNotProvidedError()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { InvalidCredentialsError, PasswordNeededError, UserDisabledError, UserNo
|
|||||||
import { UsernameOrEmailNeededError } from '../../../errors/UserErrors';
|
import { UsernameOrEmailNeededError } from '../../../errors/UserErrors';
|
||||||
import { JwtCreator } from '../../../jwtcreator';
|
import { JwtCreator } from '../../../jwtcreator';
|
||||||
import { User } from '../../entities/User';
|
import { User } from '../../entities/User';
|
||||||
import { Auth } from '../../responses/ResponseAuth';
|
import { ResponseAuth } from '../../responses/ResponseAuth';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class is used to create auth credentials based on user credentials provided in a json body (post request).
|
* This class is used to create auth credentials based on user credentials provided in a json body (post request).
|
||||||
@@ -42,8 +42,8 @@ export class CreateAuth {
|
|||||||
/**
|
/**
|
||||||
* Creates a new auth object based on this.
|
* Creates a new auth object based on this.
|
||||||
*/
|
*/
|
||||||
public async toAuth(): Promise<Auth> {
|
public async toAuth(): Promise<ResponseAuth> {
|
||||||
let newAuth: Auth = new Auth();
|
let newAuth: ResponseAuth = new ResponseAuth();
|
||||||
|
|
||||||
if (this.email === undefined && this.username === undefined) {
|
if (this.email === undefined && this.username === undefined) {
|
||||||
throw new UsernameOrEmailNeededError();
|
throw new UsernameOrEmailNeededError();
|
||||||
|
|||||||
39
src/models/actions/update/UpdateUserGroup.ts
Normal file
39
src/models/actions/update/UpdateUserGroup.ts
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
import { IsInt, IsOptional, IsString } from 'class-validator';
|
||||||
|
import { UserGroup } from '../../entities/UserGroup';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class is used to update a UserGroup entity (via put request).
|
||||||
|
*/
|
||||||
|
export class UpdateUserGroup {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The updated group's id.
|
||||||
|
* This shouldn't have changed but it is here in case anyone ever wants to enable id changes (whyever they would want to).
|
||||||
|
*/
|
||||||
|
@IsInt()
|
||||||
|
id: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The updated group's name.
|
||||||
|
*/
|
||||||
|
@IsString()
|
||||||
|
name: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The updated groups's description.
|
||||||
|
*/
|
||||||
|
@IsString()
|
||||||
|
@IsOptional()
|
||||||
|
description?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates a group entity based on this.
|
||||||
|
* @param group The group that shall be updated.
|
||||||
|
*/
|
||||||
|
public async update(group: UserGroup): Promise<UserGroup> {
|
||||||
|
group.name = this.name;
|
||||||
|
group.description = this.description;
|
||||||
|
|
||||||
|
return group;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user