mirror of https://github.com/BRAVO68WEB/shx.git
Merge branch 'dev' of github.com:BRAVO68WEB/shx into feature/api-integration
This commit is contained in:
commit
3b7c9f1ea4
|
@ -15,13 +15,16 @@ export default class APIKeyController
|
|||
next: NextFunction
|
||||
): Promise<Response | void> => {
|
||||
let apikeys;
|
||||
let metadata;
|
||||
try {
|
||||
const { masterkey } = req.query as { masterkey: string };
|
||||
apikeys = await this.listS(masterkey);
|
||||
const { data, meta } = await this.listS(masterkey);
|
||||
apikeys = data;
|
||||
metadata = meta;
|
||||
} catch (error) {
|
||||
return next(error);
|
||||
}
|
||||
return res.status(200).json(makeResponse(apikeys));
|
||||
return res.status(200).json(makeResponse(apikeys, metadata));
|
||||
};
|
||||
|
||||
public generate = async (
|
||||
|
|
|
@ -126,12 +126,12 @@ export default class GistController
|
|||
limit: string;
|
||||
page: string;
|
||||
};
|
||||
const gists = await this.listGistsS(
|
||||
const { data, meta } = await this.listGistsS(
|
||||
search,
|
||||
parseInt(page),
|
||||
parseInt(limit)
|
||||
);
|
||||
res.status(200).json(makeResponse(gists));
|
||||
res.status(200).json(makeResponse(data, meta));
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
|
|
|
@ -125,9 +125,21 @@ export default class UploadController
|
|||
next: NextFunction
|
||||
): Promise<Response | void> => {
|
||||
try {
|
||||
const { limit, offset, query = '' } = req.query;
|
||||
const data = await this.listFilesS(query, Number(limit), Number(offset));
|
||||
res.status(200).json(makeResponse(data));
|
||||
const {
|
||||
limit,
|
||||
page,
|
||||
query = '',
|
||||
} = req.query as {
|
||||
limit: string;
|
||||
page: string;
|
||||
query: string;
|
||||
};
|
||||
const { data, meta } = await this.listFilesS(
|
||||
query,
|
||||
parseInt(limit),
|
||||
parseInt(page)
|
||||
);
|
||||
res.status(200).json(makeResponse(data, meta));
|
||||
} catch (error: any) {
|
||||
next(error);
|
||||
}
|
||||
|
|
|
@ -96,13 +96,17 @@ export default class URLStoreController
|
|||
next: NextFunction
|
||||
): Promise<Response | void> => {
|
||||
try {
|
||||
const { query, limit, page } = req.query;
|
||||
const urlstore = await this.getAllURLS(
|
||||
query as string,
|
||||
Number(limit),
|
||||
Number(page)
|
||||
const { query, limit, page } = req.query as {
|
||||
query: string;
|
||||
limit: string;
|
||||
page: string;
|
||||
};
|
||||
const { data, meta } = await this.getAllURLS(
|
||||
query,
|
||||
parseInt(limit),
|
||||
parseInt(page)
|
||||
);
|
||||
res.status(200).json(makeResponse(urlstore));
|
||||
res.status(200).json(makeResponse(data, meta));
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { NextFunction, Response } from 'express';
|
||||
import { ModRequest } from '../types';
|
||||
import { Apikeys } from '../graphql/types';
|
||||
import { encapDataKey } from '../libs'
|
||||
import { encapDataKey } from '../libs';
|
||||
|
||||
export interface IAPIKeyController {
|
||||
list(
|
||||
|
@ -27,13 +27,20 @@ export interface IAPIKeyController {
|
|||
}
|
||||
|
||||
export interface IAPIKeyService {
|
||||
listS(masterkey: string): Promise<encapDataKey[]>;
|
||||
listS(masterkey: string): Promise<IListAPIKeys>;
|
||||
generateS(masterkey: string): Promise<Apikeys>;
|
||||
deleteS(apikey: string, masterkey: string): Promise<number>;
|
||||
checkS(apikey: string): Promise<Apikeys | null>;
|
||||
verifyS(apikey: string): Promise<boolean>;
|
||||
}
|
||||
|
||||
export interface IListAPIKeys {
|
||||
data: encapDataKey[];
|
||||
meta: {
|
||||
total: number;
|
||||
};
|
||||
}
|
||||
|
||||
export interface IAPIKeyAuth {
|
||||
check(req: ModRequest, res: Response, next: NextFunction): Promise<void>;
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ export interface IGistService {
|
|||
searchString: string,
|
||||
pageNo: number,
|
||||
pageSize: number
|
||||
): Promise<Gists[]>;
|
||||
): Promise<IListGists>;
|
||||
}
|
||||
|
||||
export interface IPrivate {
|
||||
|
@ -40,3 +40,13 @@ export interface IPrivate {
|
|||
export interface GistRep extends Gists {
|
||||
gist_url?: string;
|
||||
}
|
||||
|
||||
export interface IListGists {
|
||||
data: Gists[];
|
||||
meta: {
|
||||
total: number;
|
||||
pageNo: number;
|
||||
pageSize: number;
|
||||
totalPages: number;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -52,10 +52,20 @@ export interface IUploaderService {
|
|||
searchQuery: any,
|
||||
limit: number,
|
||||
offset: number
|
||||
): Promise<Uploads[]>;
|
||||
): Promise<IListUploads>;
|
||||
getFileS(fileID: string): Promise<Uploads>;
|
||||
}
|
||||
|
||||
export interface IListUploads {
|
||||
data: Uploads[];
|
||||
meta: {
|
||||
total: number;
|
||||
pageNo: number;
|
||||
pageSize: number;
|
||||
totalPages: number;
|
||||
};
|
||||
}
|
||||
|
||||
export interface UploaderConfig {
|
||||
mimeFilters: string[];
|
||||
}
|
||||
|
|
|
@ -43,11 +43,21 @@ export interface IURLStoreService {
|
|||
searchQuery: string,
|
||||
limit: number,
|
||||
offset: number
|
||||
): Promise<Shorturls[]>;
|
||||
): Promise<IListURLS>;
|
||||
getaURLS(urlID: string): Promise<Shorturls>;
|
||||
updateURLS(urlKey: string, updateObject: any): Promise<number>;
|
||||
}
|
||||
|
||||
export interface IListURLS {
|
||||
data: Shorturls[];
|
||||
meta: {
|
||||
total: number;
|
||||
pageNo: number;
|
||||
pageSize: number;
|
||||
totalPages: number;
|
||||
};
|
||||
}
|
||||
|
||||
export interface URLStoreRep extends Shorturls {
|
||||
url?: string;
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import APIKeyAuth from '../middlewares/apikey_check';
|
|||
import {
|
||||
deleteFileValidation,
|
||||
urlUploadValidation,
|
||||
listFileValidation,
|
||||
} from '../validators/upload.validation';
|
||||
|
||||
const uploadController = new UploadController();
|
||||
|
@ -45,7 +46,12 @@ router.post(
|
|||
uploadController.uploadFileFromURL as any
|
||||
);
|
||||
|
||||
router.get('/', apiKeyAuth.check as any, uploadController.getAllFiles as any);
|
||||
router.get(
|
||||
'/',
|
||||
apiKeyAuth.check as any,
|
||||
listFileValidation as any,
|
||||
uploadController.getAllFiles as any
|
||||
);
|
||||
|
||||
router.get(
|
||||
'/:fileID',
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
import { gql } from 'graphql-request';
|
||||
import { client } from '../helpers';
|
||||
import { IAPIKeyService } from '../interfaces/apikey.interface';
|
||||
import { IAPIKeyService, IListAPIKeys } from '../interfaces/apikey.interface';
|
||||
import { encapDataKeys } from '../libs';
|
||||
import { Apikeys, Apikeys_Mutation_Response } from '../graphql/types';
|
||||
import { encapDataKey } from '../libs';
|
||||
export default class APIKeyService implements IAPIKeyService {
|
||||
public async checkS(apikey: string): Promise<Apikeys | null> {
|
||||
const query = gql`
|
||||
|
@ -25,7 +24,6 @@ export default class APIKeyService implements IAPIKeyService {
|
|||
if (result.apikeys.length === 0) {
|
||||
return null;
|
||||
} else {
|
||||
// return result.apikeys[0];
|
||||
const updateLastUsedquery = gql`
|
||||
mutation updateLastUsed($apikeyID: uuid!) {
|
||||
update_apikeys_by_pk(
|
||||
|
@ -84,7 +82,7 @@ export default class APIKeyService implements IAPIKeyService {
|
|||
return result.delete_apikeys.affected_rows;
|
||||
}
|
||||
|
||||
public async listS(masterKey: string): Promise<encapDataKey[]> {
|
||||
public async listS(masterKey: string): Promise<IListAPIKeys> {
|
||||
if (masterKey !== process.env.MASTER_KEY)
|
||||
throw new Error('Invalid master key');
|
||||
const query = gql`
|
||||
|
@ -94,12 +92,28 @@ export default class APIKeyService implements IAPIKeyService {
|
|||
keyID
|
||||
last_used
|
||||
}
|
||||
|
||||
apikeys_aggregate {
|
||||
aggregate {
|
||||
count
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
const result: {
|
||||
apikeys: Apikeys[];
|
||||
apikeys_aggregate: {
|
||||
aggregate: {
|
||||
count: number;
|
||||
};
|
||||
};
|
||||
} = await client.request(query);
|
||||
return encapDataKeys(result.apikeys);
|
||||
return {
|
||||
data: encapDataKeys(result.apikeys),
|
||||
meta: {
|
||||
total: result.apikeys_aggregate.aggregate.count,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
public async verifyS(apikey: string): Promise<boolean> {
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
import { gql } from 'graphql-request';
|
||||
import { client } from '../helpers';
|
||||
import { IGistService, IPrivate } from '../interfaces/gists.interface';
|
||||
import {
|
||||
IGistService,
|
||||
IListGists,
|
||||
IPrivate,
|
||||
} from '../interfaces/gists.interface';
|
||||
import { UserMeta } from '../types';
|
||||
import { Gists, Gists_Mutation_Response } from '../graphql/types';
|
||||
|
||||
|
@ -127,7 +131,7 @@ export default class GistService implements IGistService {
|
|||
searchString = '',
|
||||
pageNo = 1,
|
||||
pageSize = 10
|
||||
): Promise<Gists[]> {
|
||||
): Promise<IListGists> {
|
||||
const query = gql`
|
||||
query listGists($searchString: String!, $pageNo: Int!, $pageSize: Int!) {
|
||||
gists(
|
||||
|
@ -148,6 +152,19 @@ export default class GistService implements IGistService {
|
|||
isOneTimeOnly
|
||||
views
|
||||
}
|
||||
|
||||
gists_aggregate(
|
||||
where: {
|
||||
_or: [
|
||||
{ content: { _iregex: $searchString } }
|
||||
{ gist_url_key: { _iregex: $searchString } }
|
||||
]
|
||||
}
|
||||
) {
|
||||
aggregate {
|
||||
count
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
const variables = {
|
||||
|
@ -157,8 +174,29 @@ export default class GistService implements IGistService {
|
|||
};
|
||||
const result: {
|
||||
gists: Gists[];
|
||||
gists_aggregate: {
|
||||
aggregate: {
|
||||
count: number;
|
||||
};
|
||||
};
|
||||
} = await client.request(query, variables);
|
||||
return result.gists;
|
||||
result.gists = result.gists.map(gist => {
|
||||
if (gist.isPrivate) {
|
||||
gist.content = 'Locked 🔒';
|
||||
}
|
||||
return gist;
|
||||
});
|
||||
return {
|
||||
data: result.gists,
|
||||
meta: {
|
||||
pageNo,
|
||||
pageSize,
|
||||
total: result.gists_aggregate.aggregate.count,
|
||||
totalPages: Math.ceil(
|
||||
result.gists_aggregate.aggregate.count / pageSize
|
||||
),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
public async updateGistS(gistID: string, content: string): Promise<number> {
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import os from 'node:os';
|
||||
|
||||
export default class InfoService {
|
||||
static async getSystemInfo() {
|
||||
const sys = {
|
||||
|
@ -7,19 +9,8 @@ export default class InfoService {
|
|||
uptime: process.uptime(),
|
||||
memoryUsage: process.memoryUsage(),
|
||||
cpuUsage: process.cpuUsage(),
|
||||
pid: process.pid,
|
||||
ppid: process.ppid,
|
||||
cwd: process.cwd(),
|
||||
execPath: process.execPath,
|
||||
execArgv: process.execArgv,
|
||||
argv: process.argv,
|
||||
env: process.env,
|
||||
config: process.config,
|
||||
title: process.title,
|
||||
version: process.version,
|
||||
versions: process.versions,
|
||||
release: process.release,
|
||||
features: process.features,
|
||||
kernelVersion: os.release(),
|
||||
hostname: os.hostname(),
|
||||
};
|
||||
|
||||
return sys;
|
||||
|
|
|
@ -2,7 +2,7 @@ import UploaderService from '../data/uploader.service';
|
|||
import { gql } from 'graphql-request';
|
||||
import { client } from '../helpers';
|
||||
import sharp from 'sharp';
|
||||
import { IUploaderService } from '../interfaces/upload.interface';
|
||||
import { IListUploads, IUploaderService } from '../interfaces/upload.interface';
|
||||
import { UserMeta } from '../types';
|
||||
import axios from 'axios';
|
||||
import fs from 'fs';
|
||||
|
@ -333,9 +333,9 @@ export default class Uploader implements IUploaderService {
|
|||
|
||||
public listFilesS = async (
|
||||
searchQuery: any,
|
||||
limit: number,
|
||||
offset: number
|
||||
): Promise<Uploads[]> => {
|
||||
limit = 1,
|
||||
offset = 10
|
||||
): Promise<IListUploads> => {
|
||||
const query = gql`
|
||||
query listFiles($searchQuery: String!, $limit: Int!, $offset: Int!) {
|
||||
uploads(
|
||||
|
@ -373,14 +373,27 @@ export default class Uploader implements IUploaderService {
|
|||
const variables = {
|
||||
searchQuery,
|
||||
limit: limit,
|
||||
offset: offset,
|
||||
offset: (offset - 1) * limit,
|
||||
};
|
||||
|
||||
const data: {
|
||||
uploads: Uploads[];
|
||||
uploads_aggregate: {
|
||||
aggregate: {
|
||||
count: number;
|
||||
};
|
||||
};
|
||||
} = await client.request(query, variables);
|
||||
|
||||
return data.uploads;
|
||||
return {
|
||||
data: data.uploads,
|
||||
meta: {
|
||||
total: data.uploads_aggregate.aggregate.count,
|
||||
pageNo: offset,
|
||||
pageSize: limit,
|
||||
totalPages: Math.ceil(data.uploads_aggregate.aggregate.count / limit),
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
public getFileS = async (fileID: string): Promise<Uploads> => {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { gql } from 'graphql-request';
|
||||
import { client } from '../helpers';
|
||||
import { UserMeta } from '../types';
|
||||
import { IURLStoreService } from '../interfaces/urlstore.interface';
|
||||
import { IListURLS, IURLStoreService } from '../interfaces/urlstore.interface';
|
||||
import { Shorturls, Shorturls_Mutation_Response } from '../graphql/types';
|
||||
|
||||
export default class URLStore implements IURLStoreService {
|
||||
|
@ -64,8 +64,8 @@ export default class URLStore implements IURLStoreService {
|
|||
public async getAllURLS(
|
||||
searchQuery = '',
|
||||
limit = 10,
|
||||
offset = 0
|
||||
): Promise<Shorturls[]> {
|
||||
offset = 1
|
||||
): Promise<IListURLS> {
|
||||
const query = gql`
|
||||
query getAllURLS($searchQuery: String!, $limit: Int!, $offset: Int!) {
|
||||
shorturls(
|
||||
|
@ -83,17 +83,45 @@ export default class URLStore implements IURLStoreService {
|
|||
short_key
|
||||
urlID
|
||||
}
|
||||
|
||||
shorturls_aggregate(
|
||||
where: {
|
||||
_or: [
|
||||
{ short_key: { _iregex: $searchQuery } }
|
||||
{ original_url: { _iregex: $searchQuery } }
|
||||
]
|
||||
}
|
||||
) {
|
||||
aggregate {
|
||||
count
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
const variables = {
|
||||
searchQuery,
|
||||
limit,
|
||||
offset,
|
||||
offset: (offset - 1) * limit,
|
||||
};
|
||||
const result: {
|
||||
shorturls: Shorturls[];
|
||||
shorturls_aggregate: {
|
||||
aggregate: {
|
||||
count: number;
|
||||
};
|
||||
};
|
||||
} = await client.request(query, variables);
|
||||
return result.shorturls;
|
||||
return {
|
||||
data: result.shorturls,
|
||||
meta: {
|
||||
pageNo: offset,
|
||||
pageSize: limit,
|
||||
total: result.shorturls_aggregate.aggregate.count,
|
||||
totalPages: Math.ceil(
|
||||
result.shorturls_aggregate.aggregate.count / limit
|
||||
),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
public async getaURLS(urlID: string): Promise<Shorturls> {
|
||||
|
|
|
@ -49,3 +49,28 @@ export const urlUploadValidation = async (
|
|||
return;
|
||||
}
|
||||
};
|
||||
|
||||
export const listFileValidation = async (
|
||||
req: ModRequest,
|
||||
res: Response,
|
||||
next: NextFunction
|
||||
) => {
|
||||
try {
|
||||
const schema = Joi.object().keys({
|
||||
query: Joi.string().optional(),
|
||||
page: Joi.number().optional().default(1),
|
||||
limit: Joi.number().optional().default(10),
|
||||
});
|
||||
req.query = await schema.validateAsync(req.query);
|
||||
next();
|
||||
} catch (err) {
|
||||
res.status(400).send(
|
||||
new CustomError({
|
||||
data: err,
|
||||
message: ErrorMsg.VALIDATION,
|
||||
statusCode: 400,
|
||||
})
|
||||
);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -58,8 +58,8 @@ export const urlGelAllValidation = async (
|
|||
try {
|
||||
const schema = Joi.object().keys({
|
||||
query: Joi.string().optional(),
|
||||
page: Joi.number().optional(),
|
||||
limit: Joi.number().optional(),
|
||||
page: Joi.number().optional().default(1),
|
||||
limit: Joi.number().optional().default(10),
|
||||
});
|
||||
req.query = await schema.validateAsync(req.query);
|
||||
next();
|
||||
|
|
Loading…
Reference in New Issue