👕 Fix linting issues

This commit is contained in:
ricardo 2022-03-27 12:08:48 -04:00
parent 86a4eb8042
commit f5812fd8c7
5 changed files with 73 additions and 74 deletions

View file

@ -5,49 +5,43 @@ interface IPaginationOffsetDecoded {
limit: number; limit: number;
} }
export const decodeCursor = (cursor: string) export const decodeCursor = (cursor: string): IPaginationOffsetDecoded => {
: IPaginationOffsetDecoded => { const data = JSON.parse(Buffer.from(cursor, 'base64').toString()) as string;
const data = JSON.parse(Buffer.from(cursor, 'base64').toString()); const unserializedData = querystring.decode(data) as { offset: string; limit: string };
const unserializedData = querystring.decode(data) as { offset: string, limit: string };
return { return {
offset: parseInt(unserializedData.offset, 10), offset: parseInt(unserializedData.offset, 10),
limit: parseInt(unserializedData.limit, 10), limit: parseInt(unserializedData.limit, 10),
}; };
}; };
export const getNextCursor = (offset: number, limit: number, numberOfRecords: number): string | null => { export const getNextCursor = (
offset: number,
limit: number,
numberOfRecords: number,
): string | null => {
const retrieveRecordsLength = offset + limit; const retrieveRecordsLength = offset + limit;
if (retrieveRecordsLength < numberOfRecords) { if (retrieveRecordsLength < numberOfRecords) {
return Buffer.from(JSON.stringify(querystring.encode({ return Buffer.from(
limit, JSON.stringify(
offset: offset + limit, querystring.encode({
}))).toString('base64'); limit,
offset: offset + limit,
}),
),
).toString('base64');
} }
return null; return null;
}; };
export const getSelectableProperties = (table: string) => { export const getSelectableProperties = (table: 'user' | 'role'): string[] => {
return { return {
user: [ user: ['id', 'email', 'firstName', 'lastName', 'createdAt', 'updatedAt'],
'id', role: ['id', 'name', 'scope', 'createdAt', 'updatedAt'],
'email',
'firstName',
'lastName',
'createdAt',
'updatedAt',
],
role: [
'id',
'name',
'scope',
'createdAt',
'updatedAt',
],
}[table]; }[table];
}; };
export const connectionName = () => { export const connectionName = (): string => {
return 'default'; return 'default';
}; };

View file

@ -1,7 +1,4 @@
import { Application, Response } from 'express';
import {
Application,
} from 'express';
import * as OpenApiValidator from 'express-openapi-validator'; import * as OpenApiValidator from 'express-openapi-validator';
@ -10,7 +7,8 @@ import path = require('path');
import express = require('express'); import express = require('express');
import { HttpError, OpenAPIV3 } from 'express-openapi-validator/dist/framework/types'; import { HttpError, OpenAPIV3 } from 'express-openapi-validator/dist/framework/types';
import { Db, ResponseHelper } from '../..'; // eslint-disable-next-line import/no-cycle
import { Db } from '../..';
import config = require('../../../config'); import config = require('../../../config');
export interface N8nApp { export interface N8nApp {
@ -19,30 +17,32 @@ export interface N8nApp {
export const publicApiController = express.Router(); export const publicApiController = express.Router();
publicApiController.use(`/v1`, publicApiController.use(
`/v1`,
OpenApiValidator.middleware({ OpenApiValidator.middleware({
apiSpec: path.join(__dirname, 'openapi.yml'), apiSpec: path.join(__dirname, 'openapi.yml'),
operationHandlers: path.join(__dirname), operationHandlers: path.join(__dirname),
validateRequests: true, // (default) validateRequests: true,
validateApiSpec: true, validateApiSpec: true,
validateSecurity: { validateSecurity: {
handlers: { handlers: {
// eslint-disable-next-line @typescript-eslint/naming-convention
ApiKeyAuth: async (req, scopes, schema: OpenAPIV3.ApiKeySecurityScheme) => { ApiKeyAuth: async (req, scopes, schema: OpenAPIV3.ApiKeySecurityScheme) => {
const apiKey = req.headers[schema.name.toLowerCase()]; const apiKey = req.headers[schema.name.toLowerCase()];
const user = await Db.collections.User!.find({ const user = await Db.collections.User?.find({
where: { where: {
apiKey, apiKey,
}, },
relations: ['globalRole'], relations: ['globalRole'],
}); });
if (!user.length) { if (!user?.length) {
return false; return false;
} }
if (!config.get('userManagement.isInstanceOwnerSetUp')) { if (!config.get('userManagement.isInstanceOwnerSetUp')) {
// eslint-disable-next-line @typescript-eslint/no-throw-literal
throw { throw {
message: 'asasasas', message: 'asasasas',
status: 400, status: 400,
@ -50,32 +50,26 @@ publicApiController.use(`/v1`,
} }
if (user[0].globalRole.name !== 'owner') { if (user[0].globalRole.name !== 'owner') {
// eslint-disable-next-line @typescript-eslint/no-throw-literal
throw { throw {
status: 403, status: 403,
}; };
} }
req.user = user[0]; [req.user] = user;
return true; return true;
}, },
}, },
}, },
})); }),
);
//add error handler // add error handler
//@ts-ignore // @ts-ignore
publicApiController.use((err: HttpError, req, res, next) => { publicApiController.use((error: HttpError, req, res: Response) => {
res.status(err.status || 500).json({ res.status(error.status || 500).json({
message: err.message, message: error.message,
errors: err.errors, errors: error.errors,
}); });
}); });
// export const getRoutes = (): express.Router => {
// return publicApiController;
// };

View file

@ -4,27 +4,30 @@ import { getConnection } from 'typeorm';
import { UserRequest } from '../../../../requests'; import { UserRequest } from '../../../../requests';
import { User } from '../../../../databases/entities/User'; import { User } from '../../../../databases/entities/User';
import { connectionName, decodeCursor, getNextCursor, getSelectableProperties } from '../../../helpers'; import {
connectionName,
import * as config from '../../../../../config'; decodeCursor,
getNextCursor,
getSelectableProperties,
} from '../../../helpers';
export = { export = {
createUsers: async (req: UserRequest.Invite, res: express.Response) => { createUsers: async (req: UserRequest.Invite, res: express.Response): Promise<void> => {
res.json({ success: true }); res.json({ success: true });
}, },
deleteUser: async (req: UserRequest.Delete, res: express.Response) => { deleteUser: async (req: UserRequest.Delete, res: express.Response): Promise<void> => {
res.json({ success: true }); res.json({ success: true });
}, },
getUser: async (req: UserRequest.Get, res: express.Response) => { getUser: async (req: UserRequest.Get, res: express.Response): Promise<void> => {
res.json({ success: true }); res.json({ success: true });
}, },
getUsers: async (req: UserRequest.Get, res: express.Response) => { getUsers: async (req: UserRequest.Get, res: express.Response): Promise<void> => {
let offset = 0; let offset = 0;
let limit = parseInt(req.query.limit as string, 10) || 10; let limit = parseInt(req.query.limit, 10) || 10;
const includeRole = req.query?.includeRole?.toLowerCase() === 'true' || false; const includeRole = req.query?.includeRole?.toLowerCase() === 'true' || false;
if (req.query.cursor) { if (req.query.cursor) {
const cursor = req.query.cursor as string; const { cursor } = req.query;
({ offset, limit } = decodeCursor(cursor)); ({ offset, limit } = decodeCursor(cursor));
} }
@ -32,12 +35,12 @@ export = {
.getRepository(User) .getRepository(User)
.createQueryBuilder() .createQueryBuilder()
.leftJoinAndSelect('User.globalRole', 'Role') .leftJoinAndSelect('User.globalRole', 'Role')
.select(getSelectableProperties('user')!.map(property => `User.${property}`)) .select(getSelectableProperties('user')?.map((property) => `User.${property}`))
.limit(limit) .limit(limit)
.offset(offset); .offset(offset);
if (includeRole) { if (includeRole) {
query.addSelect(getSelectableProperties('role')!.map(property => `Role.${property}`)); query.addSelect(getSelectableProperties('role')?.map((property) => `Role.${property}`));
} }
const [users, count] = await query.getManyAndCount(); const [users, count] = await query.getManyAndCount();
@ -47,4 +50,4 @@ export = {
nextCursor: getNextCursor(offset, limit, count), nextCursor: getNextCursor(offset, limit, count),
}); });
}, },
}; };

View file

@ -564,24 +564,22 @@ class App {
// Public API // Public API
// ---------------------------------------- // ----------------------------------------
// test routes to create/regenerate/delete token
//test routes to create/regenerate/delete token // NOTE: Only works with admin role
//NOTE: Only works with admin role // This should be within the user's management user scope
//This should be within the user's management user scope
this.app.post('/token', async (req: express.Request, res: express.Response) => { this.app.post('/token', async (req: express.Request, res: express.Response) => {
const ramdonToken = randomBytes(20).toString('hex'); const ramdonToken = randomBytes(20).toString('hex');
//@ts-ignore // @ts-ignore
await Db.collections.User!.update({ globalRole: 1 }, { apiKey: ramdonToken }); await Db.collections.User!.update({ globalRole: 1 }, { apiKey: ramdonToken });
return ResponseHelper.sendSuccessResponse(res, { token: ramdonToken }, true, 200); return ResponseHelper.sendSuccessResponse(res, { token: ramdonToken }, true, 200);
}); });
this.app.delete('/token', async (req: express.Request, res: express.Response) => { this.app.delete('/token', async (req: express.Request, res: express.Response) => {
//@ts-ignore // @ts-ignore
await Db.collections.User!.update({ globalRole: 1 }, { apiKey: null }); await Db.collections.User!.update({ globalRole: 1 }, { apiKey: null });
return ResponseHelper.sendSuccessResponse(res, {}, true, 204); return ResponseHelper.sendSuccessResponse(res, {}, true, 204);
}); });
this.app.use(`/${this.publicApiEndpoint}/`, publicApiController); this.app.use(`/${this.publicApiEndpoint}/`, publicApiController);
// Parse cookies for easier access // Parse cookies for easier access
@ -3111,7 +3109,7 @@ async function getExecutionsCount(
try { try {
// Get an estimate of rows count. // Get an estimate of rows count.
const estimateRowsNumberSql = const estimateRowsNumberSql =
'SELECT n_live_tup FROM pg_stat_all_tables WHERE relname = \'execution_entity\';'; "SELECT n_live_tup FROM pg_stat_all_tables WHERE relname = 'execution_entity';";
const rows: Array<{ n_live_tup: string }> = await Db.collections.Execution!.query( const rows: Array<{ n_live_tup: string }> = await Db.collections.Execution!.query(
estimateRowsNumberSql, estimateRowsNumberSql,
); );

View file

@ -196,9 +196,19 @@ export declare namespace UserRequest {
{ inviterId?: string; inviteeId?: string } { inviterId?: string; inviteeId?: string }
>; >;
export type Delete = AuthenticatedRequest<{ id: string, email: string }, {}, {}, { transferId?: string }>; export type Delete = AuthenticatedRequest<
{ id: string; email: string },
{},
{},
{ transferId?: string }
>;
export type Get = AuthenticatedRequest<{ id: string, email: string }, {}, {}, { limit: string, cursor: string, includeRole: string }>; export type Get = AuthenticatedRequest<
{ id: string; email: string },
{},
{},
{ limit: string; cursor: string; includeRole: string }
>;
export type Reinvite = AuthenticatedRequest<{ id: string }>; export type Reinvite = AuthenticatedRequest<{ id: string }>;