renaming api module to webapi

This commit is contained in:
Julian Krauser 2025-01-22 09:39:31 +01:00
parent 0b40b9d92c
commit 313785b4ac
21 changed files with 247 additions and 238 deletions

View file

@ -1,15 +1,15 @@
export interface CreateApiCommand { export interface CreateWebapiCommand {
title: string; title: string;
token: string; token: string;
expiry?: Date; expiry?: Date;
} }
export interface UpdateApiCommand { export interface UpdateWebapiCommand {
id: number; id: number;
title: string; title: string;
expiry?: Date; expiry?: Date;
} }
export interface DeleteApiCommand { export interface DeleteWebapiCommand {
id: number; id: number;
} }

View file

@ -1,23 +1,23 @@
import { dataSource } from "../../../data-source"; import { dataSource } from "../../../data-source";
import { api } from "../../../entity/user/api"; import { webapi } from "../../../entity/user/webapi";
import InternalException from "../../../exceptions/internalException"; import InternalException from "../../../exceptions/internalException";
import { CreateApiCommand, DeleteApiCommand, UpdateApiCommand } from "./apiCommand"; import { CreateWebapiCommand, DeleteWebapiCommand, UpdateWebapiCommand } from "./webapiCommand";
export default abstract class ApiCommandHandler { export default abstract class WebapiCommandHandler {
/** /**
* @description create api * @description create api
* @param {CreateApiCommand} createApi * @param {CreateWebapiCommand} createWebapi
* @returns {Promise<number>} * @returns {Promise<number>}
*/ */
static async create(createApi: CreateApiCommand): Promise<number> { static async create(createWebapi: CreateWebapiCommand): Promise<number> {
return await dataSource return await dataSource
.createQueryBuilder() .createQueryBuilder()
.insert() .insert()
.into(api) .into(webapi)
.values({ .values({
token: createApi.token, token: createWebapi.token,
title: createApi.title, title: createWebapi.title,
expiry: createApi.expiry, expiry: createWebapi.expiry,
}) })
.execute() .execute()
.then((result) => { .then((result) => {
@ -30,18 +30,18 @@ export default abstract class ApiCommandHandler {
/** /**
* @description update api * @description update api
* @param {UpdateApiCommand} updateApi * @param {UpdateWebapiCommand} updateWebapi
* @returns {Promise<void>} * @returns {Promise<void>}
*/ */
static async update(updateApi: UpdateApiCommand): Promise<void> { static async update(updateWebapi: UpdateWebapiCommand): Promise<void> {
return await dataSource return await dataSource
.createQueryBuilder() .createQueryBuilder()
.update(api) .update(webapi)
.set({ .set({
title: updateApi.title, title: updateWebapi.title,
expiry: updateApi.expiry, expiry: updateWebapi.expiry,
}) })
.where("id = :id", { id: updateApi.id }) .where("id = :id", { id: updateWebapi.id })
.execute() .execute()
.then(() => {}) .then(() => {})
.catch((err) => { .catch((err) => {
@ -51,15 +51,15 @@ export default abstract class ApiCommandHandler {
/** /**
* @description delete api * @description delete api
* @param {DeleteApiCommand} deleteApi * @param {DeleteWebapiCommand} deleteWebapi
* @returns {Promise<void>} * @returns {Promise<void>}
*/ */
static async delete(deleteApi: DeleteApiCommand): Promise<void> { static async delete(deleteWebapi: DeleteWebapiCommand): Promise<void> {
return await dataSource return await dataSource
.createQueryBuilder() .createQueryBuilder()
.delete() .delete()
.from(api) .from(webapi)
.where("id = :id", { id: deleteApi.id }) .where("id = :id", { id: deleteWebapi.id })
.execute() .execute()
.then(() => {}) .then(() => {})
.catch((err) => { .catch((err) => {

View file

@ -1,16 +1,16 @@
import { PermissionString } from "../../../type/permissionTypes"; import { PermissionString } from "../../../type/permissionTypes";
export interface CreateApiPermissionCommand { export interface CreateWebapiPermissionCommand {
permission: PermissionString; permission: PermissionString;
apiId: number; apiId: number;
} }
export interface DeleteApiPermissionCommand { export interface DeleteWebapiPermissionCommand {
permission: PermissionString; permission: PermissionString;
apiId: number; apiId: number;
} }
export interface UpdateApiPermissionsCommand { export interface UpdateWebapiPermissionsCommand {
apiId: number; apiId: number;
permissions: Array<PermissionString>; permissions: Array<PermissionString>;
} }

View file

@ -1,34 +1,39 @@
import { DeleteResult, EntityManager, InsertResult } from "typeorm"; import { DeleteResult, EntityManager, InsertResult } from "typeorm";
import { dataSource } from "../../../data-source"; import { dataSource } from "../../../data-source";
import { apiPermission } from "../../../entity/user/api_permission"; import { webapiPermission } from "../../../entity/user/webapi_permission";
import InternalException from "../../../exceptions/internalException"; import InternalException from "../../../exceptions/internalException";
import ApiService from "../../../service/user/apiService"; import WebapiService from "../../../service/user/webapiService";
import { import {
CreateApiPermissionCommand, CreateWebapiPermissionCommand,
DeleteApiPermissionCommand, DeleteWebapiPermissionCommand,
UpdateApiPermissionsCommand, UpdateWebapiPermissionsCommand,
} from "./apiPermissionCommand"; } from "./webapiPermissionCommand";
import PermissionHelper from "../../../helpers/permissionHelper"; import PermissionHelper from "../../../helpers/permissionHelper";
import ApiPermissionService from "../../../service/user/apiPermissionService"; import WebapiPermissionService from "../../../service/user/webapiPermissionService";
import { PermissionString } from "../../../type/permissionTypes"; import { PermissionString } from "../../../type/permissionTypes";
export default abstract class ApiPermissionCommandHandler { export default abstract class WebapiPermissionCommandHandler {
/** /**
* @description update api permissions * @description update api permissions
* @param {UpdateApiPermissionsCommand} updateApiPermissions * @param {UpdateWebapiPermissionsCommand} updateWebapiPermissions
* @returns {Promise<void>} * @returns {Promise<void>}
*/ */
static async updatePermissions(updateApiPermissions: UpdateApiPermissionsCommand): Promise<void> { static async updatePermissions(updateWebapiPermissions: UpdateWebapiPermissionsCommand): Promise<void> {
let currentPermissions = (await ApiPermissionService.getByApi(updateApiPermissions.apiId)).map((r) => r.permission); let currentPermissions = (await WebapiPermissionService.getByApi(updateWebapiPermissions.apiId)).map(
(r) => r.permission
);
return await dataSource.manager return await dataSource.manager
.transaction(async (manager) => { .transaction(async (manager) => {
let newPermissions = PermissionHelper.getWhatToAdd(currentPermissions, updateApiPermissions.permissions); let newPermissions = PermissionHelper.getWhatToAdd(currentPermissions, updateWebapiPermissions.permissions);
let removePermissions = PermissionHelper.getWhatToRemove(currentPermissions, updateApiPermissions.permissions); let removePermissions = PermissionHelper.getWhatToRemove(
currentPermissions,
updateWebapiPermissions.permissions
);
if (newPermissions.length != 0) { if (newPermissions.length != 0) {
await this.updatePermissionsAdd(manager, updateApiPermissions.apiId, newPermissions); await this.updatePermissionsAdd(manager, updateWebapiPermissions.apiId, newPermissions);
} }
if (removePermissions.length != 0) { if (removePermissions.length != 0) {
await this.updatePermissionsRemove(manager, updateApiPermissions.apiId, removePermissions); await this.updatePermissionsRemove(manager, updateWebapiPermissions.apiId, removePermissions);
} }
}) })
.then(() => {}) .then(() => {})
@ -39,17 +44,17 @@ export default abstract class ApiPermissionCommandHandler {
private static async updatePermissionsAdd( private static async updatePermissionsAdd(
manager: EntityManager, manager: EntityManager,
apiId: number, webapiId: number,
permissions: Array<PermissionString> permissions: Array<PermissionString>
): Promise<InsertResult> { ): Promise<InsertResult> {
return await manager return await manager
.createQueryBuilder() .createQueryBuilder()
.insert() .insert()
.into(apiPermission) .into(webapiPermission)
.values( .values(
permissions.map((p) => ({ permissions.map((p) => ({
permission: p, permission: p,
apiId: apiId, apiId: webapiId,
})) }))
) )
.orIgnore() .orIgnore()
@ -58,31 +63,31 @@ export default abstract class ApiPermissionCommandHandler {
private static async updatePermissionsRemove( private static async updatePermissionsRemove(
manager: EntityManager, manager: EntityManager,
apiId: number, webapiId: number,
permissions: Array<PermissionString> permissions: Array<PermissionString>
): Promise<DeleteResult> { ): Promise<DeleteResult> {
return await manager return await manager
.createQueryBuilder() .createQueryBuilder()
.delete() .delete()
.from(apiPermission) .from(webapiPermission)
.where("apiId = :id", { id: apiId }) .where("webapiId = :id", { id: webapiId })
.andWhere("permission IN (:...permission)", { permission: permissions }) .andWhere("permission IN (:...permission)", { permission: permissions })
.execute(); .execute();
} }
/** /**
* @description grant permission to user * @description grant permission to user
* @param {CreateApiPermissionCommand} createPermission * @param {CreateWebapiPermissionCommand} createPermission
* @returns {Promise<number>} * @returns {Promise<number>}
*/ */
static async create(createPermission: CreateApiPermissionCommand): Promise<number> { static async create(createPermission: CreateWebapiPermissionCommand): Promise<number> {
return await dataSource return await dataSource
.createQueryBuilder() .createQueryBuilder()
.insert() .insert()
.into(apiPermission) .into(webapiPermission)
.values({ .values({
permission: createPermission.permission, permission: createPermission.permission,
apiId: createPermission.apiId, webapiId: createPermission.apiId,
}) })
.execute() .execute()
.then((result) => { .then((result) => {
@ -95,15 +100,15 @@ export default abstract class ApiPermissionCommandHandler {
/** /**
* @description remove permission from api * @description remove permission from api
* @param {DeleteApiPermissionCommand} deletePermission * @param {DeleteWebapiPermissionCommand} deletePermission
* @returns {Promise<any>} * @returns {Promise<any>}
*/ */
static async delete(deletePermission: DeleteApiPermissionCommand): Promise<any> { static async delete(deletePermission: DeleteWebapiPermissionCommand): Promise<any> {
return await dataSource return await dataSource
.createQueryBuilder() .createQueryBuilder()
.delete() .delete()
.from(apiPermission) .from(webapiPermission)
.where("apiId = :id", { id: deletePermission.apiId }) .where("webapiId = :id", { id: deletePermission.apiId })
.andWhere("permission = :permission", { permission: deletePermission.permission }) .andWhere("permission = :permission", { permission: deletePermission.permission })
.execute() .execute()
.then(() => {}) .then(() => {})

View file

@ -1,12 +1,16 @@
import { Request, Response } from "express"; import { Request, Response } from "express";
import ApiService from "../../../service/user/apiService"; import WebapiService from "../../../service/user/webapiService";
import ApiFactory from "../../../factory/admin/user/api"; import ApiFactory from "../../../factory/admin/user/webapi";
import ApiPermissionService from "../../../service/user/apiPermissionService"; import WebapiPermissionService from "../../../service/user/webapiPermissionService";
import PermissionHelper from "../../../helpers/permissionHelper"; import PermissionHelper from "../../../helpers/permissionHelper";
import { CreateApiCommand, DeleteApiCommand, UpdateApiCommand } from "../../../command/user/api/apiCommand"; import {
import ApiCommandHandler from "../../../command/user/api/apiCommandHandler"; CreateWebapiCommand,
import { UpdateApiPermissionsCommand } from "../../../command/user/api/apiPermissionCommand"; DeleteWebapiCommand,
import ApiPermissionCommandHandler from "../../../command/user/api/apiPermissionCommandHandler"; UpdateWebapiCommand,
} from "../../../command/user/webapi/webapiCommand";
import WebapiCommandHandler from "../../../command/user/webapi/webapiCommandHandler";
import { UpdateWebapiPermissionsCommand } from "../../../command/user/webapi/webapiPermissionCommand";
import WebapiPermissionCommandHandler from "../../../command/user/webapi/webapiPermissionCommandHandler";
import { JWTHelper } from "../../../helpers/jwtHelper"; import { JWTHelper } from "../../../helpers/jwtHelper";
import { CLUB_NAME } from "../../../env.defaults"; import { CLUB_NAME } from "../../../env.defaults";
import { StringHelper } from "../../../helpers/stringHelper"; import { StringHelper } from "../../../helpers/stringHelper";
@ -17,8 +21,8 @@ import { StringHelper } from "../../../helpers/stringHelper";
* @param res {Response} Express res object * @param res {Response} Express res object
* @returns {Promise<*>} * @returns {Promise<*>}
*/ */
export async function getAllApis(req: Request, res: Response): Promise<any> { export async function getAllWebapis(req: Request, res: Response): Promise<any> {
let apis = await ApiService.getAll(); let apis = await WebapiService.getAll();
res.json(ApiFactory.mapToBase(apis)); res.json(ApiFactory.mapToBase(apis));
} }
@ -29,9 +33,9 @@ export async function getAllApis(req: Request, res: Response): Promise<any> {
* @param res {Response} Express res object * @param res {Response} Express res object
* @returns {Promise<*>} * @returns {Promise<*>}
*/ */
export async function getApiById(req: Request, res: Response): Promise<any> { export async function getWebapiById(req: Request, res: Response): Promise<any> {
const id = parseInt(req.params.id); const id = parseInt(req.params.id);
let api = await ApiService.getById(id); let api = await WebapiService.getById(id);
res.json(ApiFactory.mapToSingle(api)); res.json(ApiFactory.mapToSingle(api));
} }
@ -42,9 +46,9 @@ export async function getApiById(req: Request, res: Response): Promise<any> {
* @param res {Response} Express res object * @param res {Response} Express res object
* @returns {Promise<*>} * @returns {Promise<*>}
*/ */
export async function getApiTokenById(req: Request, res: Response): Promise<any> { export async function getWebapiTokenById(req: Request, res: Response): Promise<any> {
const id = parseInt(req.params.id); const id = parseInt(req.params.id);
let { token } = await ApiService.getTokenById(id); let { token } = await WebapiService.getTokenById(id);
res.send(token); res.send(token);
} }
@ -55,9 +59,9 @@ export async function getApiTokenById(req: Request, res: Response): Promise<any>
* @param res {Response} Express res object * @param res {Response} Express res object
* @returns {Promise<*>} * @returns {Promise<*>}
*/ */
export async function getApiPermissions(req: Request, res: Response): Promise<any> { export async function getWebapiPermissions(req: Request, res: Response): Promise<any> {
const id = parseInt(req.params.id); const id = parseInt(req.params.id);
let permissions = await ApiPermissionService.getByApi(id); let permissions = await WebapiPermissionService.getByApi(id);
res.json(PermissionHelper.convertToObject(permissions.map((p) => p.permission))); res.json(PermissionHelper.convertToObject(permissions.map((p) => p.permission)));
} }
@ -68,7 +72,7 @@ export async function getApiPermissions(req: Request, res: Response): Promise<an
* @param res {Response} Express res object * @param res {Response} Express res object
* @returns {Promise<*>} * @returns {Promise<*>}
*/ */
export async function createApi(req: Request, res: Response): Promise<any> { export async function createWebapi(req: Request, res: Response): Promise<any> {
let title = req.body.title; let title = req.body.title;
let expiry = req.body.expiry; let expiry = req.body.expiry;
@ -79,12 +83,12 @@ export async function createApi(req: Request, res: Response): Promise<any> {
aud: StringHelper.random(32), aud: StringHelper.random(32),
}); });
let createApi: CreateApiCommand = { let createApi: CreateWebapiCommand = {
token: token, token: token,
title: title, title: title,
expiry: expiry, expiry: expiry,
}; };
await ApiCommandHandler.create(createApi); await WebapiCommandHandler.create(createApi);
res.sendStatus(204); res.sendStatus(204);
} }
@ -95,17 +99,17 @@ export async function createApi(req: Request, res: Response): Promise<any> {
* @param res {Response} Express res object * @param res {Response} Express res object
* @returns {Promise<*>} * @returns {Promise<*>}
*/ */
export async function updateApi(req: Request, res: Response): Promise<any> { export async function updateWebapi(req: Request, res: Response): Promise<any> {
const id = parseInt(req.params.id); const id = parseInt(req.params.id);
let title = req.body.title; let title = req.body.title;
let expiry = req.body.expiry; let expiry = req.body.expiry;
let updateApi: UpdateApiCommand = { let updateApi: UpdateWebapiCommand = {
id: id, id: id,
title: title, title: title,
expiry: expiry, expiry: expiry,
}; };
await ApiCommandHandler.update(updateApi); await WebapiCommandHandler.update(updateApi);
res.sendStatus(204); res.sendStatus(204);
} }
@ -116,17 +120,17 @@ export async function updateApi(req: Request, res: Response): Promise<any> {
* @param res {Response} Express res object * @param res {Response} Express res object
* @returns {Promise<*>} * @returns {Promise<*>}
*/ */
export async function updateApiPermissions(req: Request, res: Response): Promise<any> { export async function updateWebapiPermissions(req: Request, res: Response): Promise<any> {
const id = parseInt(req.params.id); const id = parseInt(req.params.id);
let permissions = req.body.permissions; let permissions = req.body.permissions;
let permissionStrings = PermissionHelper.convertToStringArray(permissions); let permissionStrings = PermissionHelper.convertToStringArray(permissions);
let updateApiPermissions: UpdateApiPermissionsCommand = { let updateApiPermissions: UpdateWebapiPermissionsCommand = {
apiId: id, apiId: id,
permissions: permissionStrings, permissions: permissionStrings,
}; };
await ApiPermissionCommandHandler.updatePermissions(updateApiPermissions); await WebapiPermissionCommandHandler.updatePermissions(updateApiPermissions);
res.sendStatus(204); res.sendStatus(204);
} }
@ -137,13 +141,13 @@ export async function updateApiPermissions(req: Request, res: Response): Promise
* @param res {Response} Express res object * @param res {Response} Express res object
* @returns {Promise<*>} * @returns {Promise<*>}
*/ */
export async function deleteApi(req: Request, res: Response): Promise<any> { export async function deleteWebapi(req: Request, res: Response): Promise<any> {
const id = parseInt(req.params.id); const id = parseInt(req.params.id);
let deleteApi: DeleteApiCommand = { let deleteApi: DeleteWebapiCommand = {
id: id, id: id,
}; };
await ApiCommandHandler.delete(deleteApi); await WebapiCommandHandler.delete(deleteApi);
res.sendStatus(204); res.sendStatus(204);
} }

View file

@ -8,7 +8,7 @@ import UserService from "../service/user/userService";
import speakeasy from "speakeasy"; import speakeasy from "speakeasy";
import UnauthorizedRequestException from "../exceptions/unauthorizedRequestException"; import UnauthorizedRequestException from "../exceptions/unauthorizedRequestException";
import RefreshService from "../service/refreshService"; import RefreshService from "../service/refreshService";
import ApiService from "../service/user/apiService"; import WebapiService from "../service/user/webapiService";
import ForbiddenRequestException from "../exceptions/forbiddenRequestException"; import ForbiddenRequestException from "../exceptions/forbiddenRequestException";
/** /**
@ -20,13 +20,13 @@ import ForbiddenRequestException from "../exceptions/forbiddenRequestException";
export async function getWebApiAccess(req: Request, res: Response): Promise<any> { export async function getWebApiAccess(req: Request, res: Response): Promise<any> {
const bearer = req.headers.authorization?.split(" ")?.[1] ?? undefined; const bearer = req.headers.authorization?.split(" ")?.[1] ?? undefined;
let { expiry } = await ApiService.getByToken(bearer); let { expiry } = await WebapiService.getByToken(bearer);
if (new Date() > new Date(expiry)) { if (new Date() > new Date(expiry)) {
throw new ForbiddenRequestException("api token expired"); throw new ForbiddenRequestException("api token expired");
} }
let accessToken = await JWTHelper.buildApiToken(bearer); let accessToken = await JWTHelper.buildWebapiToken(bearer);
res.json({ res.json({
accessToken, accessToken,

View file

@ -68,9 +68,9 @@ import { Memberlist1736079005086 } from "./migrations/1736079005086-memberlist";
import { ExtendViewValues1736084198860 } from "./migrations/1736084198860-extendViewValues"; import { ExtendViewValues1736084198860 } from "./migrations/1736084198860-extendViewValues";
import { FinishInternalIdTransfer1736505324488 } from "./migrations/1736505324488-finishInternalIdTransfer"; import { FinishInternalIdTransfer1736505324488 } from "./migrations/1736505324488-finishInternalIdTransfer";
import { ProtocolPresenceExcuse1737287798828 } from "./migrations/1737287798828-protocolPresenceExcuse"; import { ProtocolPresenceExcuse1737287798828 } from "./migrations/1737287798828-protocolPresenceExcuse";
import { api } from "./entity/user/api"; import { webapi } from "./entity/user/webapi";
import { apiPermission } from "./entity/user/api_permission"; import { webapiPermission } from "./entity/user/webapi_permission";
import { AddApiTokens1737453096674 } from "./migrations/1737453096674-addApiTokens"; import { AddWebapiTokens1737453096674 } from "./migrations/1737453096674-addwebapiTokens";
const dataSource = new DataSource({ const dataSource = new DataSource({
type: DB_TYPE as any, type: DB_TYPE as any,
@ -120,8 +120,8 @@ const dataSource = new DataSource({
memberExecutivePositionsView, memberExecutivePositionsView,
memberQualificationsView, memberQualificationsView,
membershipView, membershipView,
api, webapi,
apiPermission, webapiPermission,
], ],
migrations: [ migrations: [
Initial1724317398939, Initial1724317398939,
@ -151,7 +151,7 @@ const dataSource = new DataSource({
ExtendViewValues1736084198860, ExtendViewValues1736084198860,
FinishInternalIdTransfer1736505324488, FinishInternalIdTransfer1736505324488,
ProtocolPresenceExcuse1737287798828, ProtocolPresenceExcuse1737287798828,
AddApiTokens1737453096674, AddWebapiTokens1737453096674,
], ],
migrationsRun: true, migrationsRun: true,
migrationsTransactionMode: "each", migrationsTransactionMode: "each",

View file

@ -1,8 +1,8 @@
import { Column, CreateDateColumn, Entity, OneToMany, PrimaryColumn } from "typeorm"; import { Column, CreateDateColumn, Entity, OneToMany, PrimaryColumn } from "typeorm";
import { apiPermission } from "./api_permission"; import { webapiPermission } from "./webapi_permission";
@Entity() @Entity()
export class api { export class webapi {
@PrimaryColumn({ generated: "increment", type: "int" }) @PrimaryColumn({ generated: "increment", type: "int" })
id: number; id: number;
@ -21,6 +21,6 @@ export class api {
@Column({ type: "datetime", nullable: true }) @Column({ type: "datetime", nullable: true })
expiry?: Date; expiry?: Date;
@OneToMany(() => apiPermission, (apiPermission) => apiPermission.api) @OneToMany(() => webapiPermission, (apiPermission) => apiPermission.webapi)
permissions: apiPermission[]; permissions: webapiPermission[];
} }

View file

@ -1,19 +1,19 @@
import { Column, Entity, ManyToOne, OneToMany, PrimaryColumn } from "typeorm"; import { Column, Entity, ManyToOne, OneToMany, PrimaryColumn } from "typeorm";
import { PermissionObject, PermissionString } from "../../type/permissionTypes"; import { PermissionObject, PermissionString } from "../../type/permissionTypes";
import { api } from "./api"; import { webapi } from "./webapi";
@Entity() @Entity()
export class apiPermission { export class webapiPermission {
@PrimaryColumn({ type: "int" }) @PrimaryColumn({ type: "int" })
apiId: number; webapiId: number;
@PrimaryColumn({ type: "varchar", length: 255 }) @PrimaryColumn({ type: "varchar", length: 255 })
permission: PermissionString; permission: PermissionString;
@ManyToOne(() => api, { @ManyToOne(() => webapi, {
nullable: false, nullable: false,
onDelete: "CASCADE", onDelete: "CASCADE",
onUpdate: "RESTRICT", onUpdate: "RESTRICT",
}) })
api: api; webapi: webapi;
} }

View file

@ -1,14 +1,14 @@
import { api } from "../../../entity/user/api"; import { webapi } from "../../../entity/user/webapi";
import PermissionHelper from "../../../helpers/permissionHelper"; import PermissionHelper from "../../../helpers/permissionHelper";
import { ApiViewModel } from "../../../viewmodel/admin/user/api.models"; import { ApiViewModel } from "../../../viewmodel/admin/user/webapi.models";
export default abstract class ApiFactory { export default abstract class ApiFactory {
/** /**
* @description map record to api * @description map record to api
* @param {api} record * @param {webapi} record
* @returns {apiViewModel} * @returns {apiViewModel}
*/ */
public static mapToSingle(record: api): ApiViewModel { public static mapToSingle(record: webapi): ApiViewModel {
return { return {
id: record.id, id: record.id,
permissions: PermissionHelper.convertToObject(record.permissions.map((e) => e.permission)), permissions: PermissionHelper.convertToObject(record.permissions.map((e) => e.permission)),
@ -21,10 +21,10 @@ export default abstract class ApiFactory {
/** /**
* @description map records to api * @description map records to api
* @param {Array<api>} records * @param {Array<webapi>} records
* @returns {Array<apiViewModel>} * @returns {Array<apiViewModel>}
*/ */
public static mapToBase(records: Array<api>): Array<ApiViewModel> { public static mapToBase(records: Array<webapi>): Array<ApiViewModel> {
return records.map((r) => this.mapToSingle(r)); return records.map((r) => this.mapToSingle(r));
} }
} }

View file

@ -6,8 +6,8 @@ import RolePermissionService from "../service/user/rolePermissionService";
import UserPermissionService from "../service/user/userPermissionService"; import UserPermissionService from "../service/user/userPermissionService";
import UserService from "../service/user/userService"; import UserService from "../service/user/userService";
import PermissionHelper from "./permissionHelper"; import PermissionHelper from "./permissionHelper";
import ApiService from "../service/user/apiService"; import WebapiService from "../service/user/webapiService";
import ApiPermissionService from "../service/user/apiPermissionService"; import WebapiPermissionService from "../service/user/webapiPermissionService";
export abstract class JWTHelper { export abstract class JWTHelper {
static validate(token: string): Promise<string | jwt.JwtPayload> { static validate(token: string): Promise<string | jwt.JwtPayload> {
@ -75,11 +75,11 @@ export abstract class JWTHelper {
}); });
} }
static async buildApiToken(token: string): Promise<string> { static async buildWebapiToken(token: string): Promise<string> {
let { id, title } = await ApiService.getByToken(token); let { id, title } = await WebapiService.getByToken(token);
let apiPermissions = await ApiPermissionService.getByApi(id); let webapiPermissions = await WebapiPermissionService.getByApi(id);
let apiPermissionStrings = apiPermissions.map((e) => e.permission); let webapiPermissionStrings = webapiPermissions.map((e) => e.permission);
let permissionObject = PermissionHelper.convertToObject(apiPermissionStrings); let permissionObject = PermissionHelper.convertToObject(webapiPermissionStrings);
let jwtData: JWTToken = { let jwtData: JWTToken = {
userId: id, userId: id,
@ -97,7 +97,7 @@ export abstract class JWTHelper {
return result; return result;
}) })
.catch((err) => { .catch((err) => {
throw new InternalException("Failed accessToken creation", err); throw new InternalException("Failed webapi accessToken creation", err);
}); });
} }
} }

View file

@ -1,7 +1,7 @@
import { Request, Response } from "express"; import { Request, Response } from "express";
import ForbiddenRequestException from "../exceptions/forbiddenRequestException"; import ForbiddenRequestException from "../exceptions/forbiddenRequestException";
export default async function preventApiAccess(req: Request, res: Response, next: Function) { export default async function preventWebapiAccess(req: Request, res: Response, next: Function) {
if (req.isWebApiRequest) { if (req.isWebApiRequest) {
throw new ForbiddenRequestException("This route cannot be accessed via webapi"); throw new ForbiddenRequestException("This route cannot be accessed via webapi");
} else { } else {

View file

@ -1,17 +1,17 @@
import { MigrationInterface, QueryRunner, Table, TableForeignKey } from "typeorm"; import { MigrationInterface, QueryRunner, Table, TableForeignKey } from "typeorm";
import { DB_TYPE } from "../env.defaults"; import { DB_TYPE } from "../env.defaults";
export class AddApiTokens1737453096674 implements MigrationInterface { export class AddWebapiTokens1737453096674 implements MigrationInterface {
name = "AddApiTokens1737453096674"; name = "AddWebApiTokens1737453096674";
public async up(queryRunner: QueryRunner): Promise<void> { public async up(queryRunner: QueryRunner): Promise<void> {
const variableType_int = DB_TYPE == "mysql" ? "int" : "integer"; const variableType_int = DB_TYPE == "mysql" ? "int" : "integer";
await queryRunner.createTable( await queryRunner.createTable(
new Table({ new Table({
name: "api", name: "webapi",
columns: [ columns: [
{ name: "id", type: variableType_int, isPrimary: true, isNullable: false }, { name: "id", type: variableType_int, isPrimary: true, isGenerated: true, generationStrategy: "increment" },
{ name: "token", type: "varchar", length: "255", isUnique: true, isNullable: false }, { name: "token", type: "varchar", length: "255", isUnique: true, isNullable: false },
{ name: "title", type: "varchar", length: "255", isNullable: false }, { name: "title", type: "varchar", length: "255", isNullable: false },
{ name: "createdAt", type: "datetime", default: "CURRENT_TIMESTAMP(6)", isNullable: false }, { name: "createdAt", type: "datetime", default: "CURRENT_TIMESTAMP(6)", isNullable: false },
@ -24,9 +24,9 @@ export class AddApiTokens1737453096674 implements MigrationInterface {
await queryRunner.createTable( await queryRunner.createTable(
new Table({ new Table({
name: "api_permission", name: "webapi_permission",
columns: [ columns: [
{ name: "apiId", type: variableType_int, isPrimary: true, isNullable: false }, { name: "webapiId", type: variableType_int, isPrimary: true, isNullable: false },
{ name: "permission", type: "varchar", length: "255", isPrimary: true, isNullable: false }, { name: "permission", type: "varchar", length: "255", isPrimary: true, isNullable: false },
], ],
}), }),
@ -34,11 +34,11 @@ export class AddApiTokens1737453096674 implements MigrationInterface {
); );
await queryRunner.createForeignKey( await queryRunner.createForeignKey(
"api_permission", "webapi_permission",
new TableForeignKey({ new TableForeignKey({
columnNames: ["apiId"], columnNames: ["webapiId"],
referencedColumnNames: ["id"], referencedColumnNames: ["id"],
referencedTableName: "api", referencedTableName: "webapi",
onDelete: "CASCADE", onDelete: "CASCADE",
onUpdate: "RESTRICT", onUpdate: "RESTRICT",
}) })
@ -46,10 +46,10 @@ export class AddApiTokens1737453096674 implements MigrationInterface {
} }
public async down(queryRunner: QueryRunner): Promise<void> { public async down(queryRunner: QueryRunner): Promise<void> {
const table = await queryRunner.getTable("api_permission"); const table = await queryRunner.getTable("webapi_permission");
const foreignKey = table.foreignKeys.find((fk) => fk.columnNames.indexOf("apiToken") !== -1); const foreignKey = table.foreignKeys.find((fk) => fk.columnNames.indexOf("webapiId") !== -1);
await queryRunner.dropForeignKey("api_permission", foreignKey); await queryRunner.dropForeignKey("webapi_permission", foreignKey);
await queryRunner.dropTable("api_permission"); await queryRunner.dropTable("webapi_permission");
await queryRunner.dropTable("api"); await queryRunner.dropTable("webapi");
} }
} }

View file

@ -21,8 +21,8 @@ import newsletter from "./club/newsletter";
import role from "./user/role"; import role from "./user/role";
import user from "./user/user"; import user from "./user/user";
import invite from "./user/invite"; import invite from "./user/invite";
import api from "./user/api"; import api from "./user/webapi";
import preventApiAccess from "../../middleware/preventWebApiAccess"; import preventWebapiAccess from "../../middleware/preventWebApiAccess";
var router = express.Router({ mergeParams: true }); var router = express.Router({ mergeParams: true });
@ -62,6 +62,6 @@ router.use("/newsletter", PermissionHelper.passCheckMiddleware("read", "club", "
router.use("/role", PermissionHelper.passCheckMiddleware("read", "user", "role"), role); router.use("/role", PermissionHelper.passCheckMiddleware("read", "user", "role"), role);
router.use("/user", PermissionHelper.passCheckMiddleware("read", "user", "user"), user); router.use("/user", PermissionHelper.passCheckMiddleware("read", "user", "user"), user);
router.use("/invite", PermissionHelper.passCheckMiddleware("read", "user", "user"), invite); router.use("/invite", PermissionHelper.passCheckMiddleware("read", "user", "user"), invite);
router.use("/webapi", preventApiAccess, PermissionHelper.passCheckMiddleware("read", "user", "webapi"), api); router.use("/webapi", preventWebapiAccess, PermissionHelper.passCheckMiddleware("read", "user", "webapi"), api);
export default router; export default router;

View file

@ -1,34 +1,34 @@
import express, { Request, Response } from "express"; import express, { Request, Response } from "express";
import PermissionHelper from "../../../helpers/permissionHelper"; import PermissionHelper from "../../../helpers/permissionHelper";
import { import {
createApi, createWebapi,
deleteApi, deleteWebapi,
getAllApis, getAllWebapis,
getApiById, getWebapiById,
getApiPermissions, getWebapiPermissions,
updateApi, updateWebapi,
updateApiPermissions, updateWebapiPermissions,
} from "../../../controller/admin/user/apiController"; } from "../../../controller/admin/user/webapiController";
var router = express.Router({ mergeParams: true }); var router = express.Router({ mergeParams: true });
router.get("/", async (req: Request, res: Response) => { router.get("/", async (req: Request, res: Response) => {
await getAllApis(req, res); await getAllWebapis(req, res);
}); });
router.get("/:id", async (req: Request, res: Response) => { router.get("/:id", async (req: Request, res: Response) => {
await getApiById(req, res); await getWebapiById(req, res);
}); });
router.get("/:id/permissions", async (req: Request, res: Response) => { router.get("/:id/permissions", async (req: Request, res: Response) => {
await getApiPermissions(req, res); await getWebapiPermissions(req, res);
}); });
router.post( router.post(
"/", "/",
PermissionHelper.passCheckMiddleware("create", "user", "webapi"), PermissionHelper.passCheckMiddleware("create", "user", "webapi"),
async (req: Request, res: Response) => { async (req: Request, res: Response) => {
await createApi(req, res); await createWebapi(req, res);
} }
); );
@ -36,7 +36,7 @@ router.patch(
"/:id", "/:id",
PermissionHelper.passCheckMiddleware("update", "user", "webapi"), PermissionHelper.passCheckMiddleware("update", "user", "webapi"),
async (req: Request, res: Response) => { async (req: Request, res: Response) => {
await updateApi(req, res); await updateWebapi(req, res);
} }
); );
@ -44,7 +44,7 @@ router.patch(
"/:id/permissions", "/:id/permissions",
PermissionHelper.passCheckMiddleware("admin", "user", "webapi"), PermissionHelper.passCheckMiddleware("admin", "user", "webapi"),
async (req: Request, res: Response) => { async (req: Request, res: Response) => {
await updateApiPermissions(req, res); await updateWebapiPermissions(req, res);
} }
); );
@ -52,7 +52,7 @@ router.delete(
"/:id", "/:id",
PermissionHelper.passCheckMiddleware("delete", "user", "webapi"), PermissionHelper.passCheckMiddleware("delete", "user", "webapi"),
async (req: Request, res: Response) => { async (req: Request, res: Response) => {
await deleteApi(req, res); await deleteWebapi(req, res);
} }
); );

View file

@ -14,7 +14,7 @@ import auth from "./auth";
import admin from "./admin/index"; import admin from "./admin/index";
import user from "./user"; import user from "./user";
import detectPWA from "../middleware/detectPWA"; import detectPWA from "../middleware/detectPWA";
import api from "./api"; import api from "./webapi";
import authenticateAPI from "../middleware/authenticateAPI"; import authenticateAPI from "../middleware/authenticateAPI";
export default (app: Express) => { export default (app: Express) => {

View file

@ -1,5 +1,5 @@
import express, { Request, Response } from "express"; import express, { Request, Response } from "express";
import { getWebApiAccess } from "../controller/apiController"; import { getWebApiAccess } from "../controller/webapiController";
var router = express.Router({ mergeParams: true }); var router = express.Router({ mergeParams: true });

View file

@ -1,83 +0,0 @@
import { dataSource } from "../../data-source";
import { api } from "../../entity/user/api";
import InternalException from "../../exceptions/internalException";
export default abstract class ApiService {
/**
* @description get apis
* @returns {Promise<Array<api>>}
*/
static async getAll(): Promise<Array<api>> {
return await dataSource
.getRepository(api)
.createQueryBuilder("api")
.leftJoinAndSelect("api.permissions", "permissions")
.getMany()
.then((res) => {
return res;
})
.catch((err) => {
throw new InternalException("apis not found", err);
});
}
/**
* @description get api by id
* @param id number
* @returns {Promise<api>}
*/
static async getById(id: number): Promise<api> {
return await dataSource
.getRepository(api)
.createQueryBuilder("api")
.leftJoinAndSelect("api.permissions", "permissions")
.where("api.id = :id", { id: id })
.getOneOrFail()
.then((res) => {
return res;
})
.catch((err) => {
throw new InternalException("api not found by id", err);
});
}
/**
* @description get api by token
* @param token string
* @returns {Promise<api>}
*/
static async getByToken(token: string): Promise<api> {
return await dataSource
.getRepository(api)
.createQueryBuilder("api")
.leftJoinAndSelect("api.permissions", "permissions")
.where("api.token = :token", { token: token })
.getOneOrFail()
.then((res) => {
return res;
})
.catch((err) => {
throw new InternalException("api not found by token", err);
});
}
/**
* @description get api by id
* @param id number
* @returns {Promise<api>}
*/
static async getTokenById(id: number): Promise<api> {
return await dataSource
.getRepository(api)
.createQueryBuilder("api")
.select("token")
.where("api.id = :id", { id: id })
.getOneOrFail()
.then((res) => {
return res;
})
.catch((err) => {
throw new InternalException("api token not found by id", err);
});
}
}

View file

@ -1,18 +1,18 @@
import { dataSource } from "../../data-source"; import { dataSource } from "../../data-source";
import { apiPermission } from "../../entity/user/api_permission"; import { webapiPermission } from "../../entity/user/webapi_permission";
import InternalException from "../../exceptions/internalException"; import InternalException from "../../exceptions/internalException";
export default abstract class ApiPermissionService { export default abstract class WebapiPermissionService {
/** /**
* @description get permission by api * @description get permission by api
* @param apiId number * @param webapiId number
* @returns {Promise<Array<apiPermission>>} * @returns {Promise<Array<webapiPermission>>}
*/ */
static async getByApi(apiId: number): Promise<Array<apiPermission>> { static async getByApi(webapiId: number): Promise<Array<webapiPermission>> {
return await dataSource return await dataSource
.getRepository(apiPermission) .getRepository(webapiPermission)
.createQueryBuilder("api_permission") .createQueryBuilder("api_permission")
.where("api_permission.apiId = :apiId", { apiId: apiId }) .where("api_permission.apiId = :apiId", { apiId: webapiId })
.getMany() .getMany()
.then((res) => { .then((res) => {
return res; return res;

View file

@ -0,0 +1,83 @@
import { dataSource } from "../../data-source";
import { webapi } from "../../entity/user/webapi";
import InternalException from "../../exceptions/internalException";
export default abstract class WebapiService {
/**
* @description get apis
* @returns {Promise<Array<webapi>>}
*/
static async getAll(): Promise<Array<webapi>> {
return await dataSource
.getRepository(webapi)
.createQueryBuilder("webapi")
.leftJoinAndSelect("webapi.permissions", "permissions")
.getMany()
.then((res) => {
return res;
})
.catch((err) => {
throw new InternalException("webapis not found", err);
});
}
/**
* @description get api by id
* @param id number
* @returns {Promise<webapi>}
*/
static async getById(id: number): Promise<webapi> {
return await dataSource
.getRepository(webapi)
.createQueryBuilder("webapi")
.leftJoinAndSelect("webapi.permissions", "permissions")
.where("webapi.id = :id", { id: id })
.getOneOrFail()
.then((res) => {
return res;
})
.catch((err) => {
throw new InternalException("webapi not found by id", err);
});
}
/**
* @description get api by token
* @param token string
* @returns {Promise<webapi>}
*/
static async getByToken(token: string): Promise<webapi> {
return await dataSource
.getRepository(webapi)
.createQueryBuilder("webapi")
.leftJoinAndSelect("webapi.permissions", "permissions")
.where("webapi.token = :token", { token: token })
.getOneOrFail()
.then((res) => {
return res;
})
.catch((err) => {
throw new InternalException("webapi not found by token", err);
});
}
/**
* @description get api by id
* @param id number
* @returns {Promise<webapi>}
*/
static async getTokenById(id: number): Promise<webapi> {
return await dataSource
.getRepository(webapi)
.createQueryBuilder("webapi")
.select("token")
.where("webapi.id = :id", { id: id })
.getOneOrFail()
.then((res) => {
return res;
})
.catch((err) => {
throw new InternalException("webapi token not found by id", err);
});
}
}