🔧 Fixes to getList endpoint
This commit is contained in:
@@ -1,168 +1,141 @@
|
||||
import type { Context, ServiceSchema } from "moleculer";
|
||||
import type { ApiSettingsSchema, GatewayResponse, IncomingRequest, Route } from "moleculer-web";
|
||||
import { IncomingMessage } from "http";
|
||||
import { Service, ServiceBroker, Context } from "moleculer";
|
||||
import ApiGateway from "moleculer-web";
|
||||
|
||||
interface Meta {
|
||||
userAgent?: string | null | undefined;
|
||||
user?: object | null | undefined;
|
||||
}
|
||||
export default class ApiService extends Service {
|
||||
public constructor(broker: ServiceBroker) {
|
||||
super(broker);
|
||||
// @ts-ignore
|
||||
this.parseServiceSchema({
|
||||
name: "api",
|
||||
mixins: [ApiGateway],
|
||||
// More info about settings: https://moleculer.services/docs/0.14/moleculer-web.html
|
||||
settings: {
|
||||
port: process.env.PORT || 3060,
|
||||
|
||||
const ApiService: ServiceSchema<ApiSettingsSchema> = {
|
||||
name: "api",
|
||||
mixins: [ApiGateway],
|
||||
routes: [
|
||||
{
|
||||
path: "/api",
|
||||
whitelist: ["**"],
|
||||
use: [],
|
||||
mergeParams: true,
|
||||
cors: {
|
||||
origin: "*",
|
||||
methods: [
|
||||
"GET",
|
||||
"OPTIONS",
|
||||
"POST",
|
||||
"PUT",
|
||||
"DELETE",
|
||||
],
|
||||
allowedHeaders: ["*"],
|
||||
exposedHeaders: [],
|
||||
credentials: false,
|
||||
maxAge: 3600,
|
||||
},
|
||||
|
||||
// More info about settings: https://moleculer.services/docs/0.14/moleculer-web.html
|
||||
settings: {
|
||||
// Exposed port
|
||||
port: process.env.PORT != null ? Number(process.env.PORT) : 3060,
|
||||
authentication: false,
|
||||
authorization: false,
|
||||
autoAliases: true,
|
||||
|
||||
// Exposed IP
|
||||
ip: "0.0.0.0",
|
||||
aliases: {},
|
||||
callingOptions: {},
|
||||
|
||||
// Global Express middlewares. More info: https://moleculer.services/docs/0.14/moleculer-web.html#Middlewares
|
||||
use: [],
|
||||
bodyParsers: {
|
||||
json: {
|
||||
strict: false,
|
||||
limit: "1MB",
|
||||
},
|
||||
urlencoded: {
|
||||
extended: true,
|
||||
limit: "1MB",
|
||||
},
|
||||
},
|
||||
mappingPolicy: "all", // Available values: "all", "restrict"
|
||||
|
||||
routes: [
|
||||
{
|
||||
path: "/api",
|
||||
|
||||
whitelist: ["**"],
|
||||
|
||||
// Route-level Express middlewares. More info: https://moleculer.services/docs/0.14/moleculer-web.html#Middlewares
|
||||
use: [],
|
||||
|
||||
// Enable/disable parameter merging method. More info: https://moleculer.services/docs/0.14/moleculer-web.html#Disable-merging
|
||||
mergeParams: true,
|
||||
|
||||
// Enable authentication. Implement the logic into `authenticate` method. More info: https://moleculer.services/docs/0.14/moleculer-web.html#Authentication
|
||||
authentication: false,
|
||||
|
||||
// Enable authorization. Implement the logic into `authorize` method. More info: https://moleculer.services/docs/0.14/moleculer-web.html#Authorization
|
||||
authorization: false,
|
||||
|
||||
// The auto-alias feature allows you to declare your route alias directly in your services.
|
||||
// The gateway will dynamically build the full routes from service schema.
|
||||
autoAliases: true,
|
||||
|
||||
aliases: {},
|
||||
|
||||
/**
|
||||
* Before call hook. You can check the request.
|
||||
*
|
||||
onBeforeCall(
|
||||
ctx: Context<unknown, Meta>,
|
||||
route: Route,
|
||||
req: IncomingRequest,
|
||||
res: GatewayResponse,
|
||||
): void {
|
||||
// Set request headers to context meta
|
||||
ctx.meta.userAgent = req.headers["user-agent"];
|
||||
}, */
|
||||
|
||||
/**
|
||||
* After call hook. You can modify the data.
|
||||
*
|
||||
onAfterCall(
|
||||
ctx: Context,
|
||||
route: Route,
|
||||
req: IncomingRequest,
|
||||
res: GatewayResponse,
|
||||
data: unknown,
|
||||
): unknown {
|
||||
// Async function which return with Promise
|
||||
// return this.doSomething(ctx, res, data);
|
||||
return data;
|
||||
}, */
|
||||
|
||||
// Calling options. More info: https://moleculer.services/docs/0.14/moleculer-web.html#Calling-options
|
||||
// callingOptions: {},
|
||||
|
||||
bodyParsers: {
|
||||
json: {
|
||||
strict: false,
|
||||
limit: "1MB",
|
||||
},
|
||||
urlencoded: {
|
||||
extended: true,
|
||||
limit: "1MB",
|
||||
// Enable/disable logging
|
||||
logging: true,
|
||||
},
|
||||
],
|
||||
// Do not log client side errors (does not log an error response when the error.code is 400<=X<500)
|
||||
log4XXResponses: false,
|
||||
// Logging the request parameters. Set to any log level to enable it. E.g. "info"
|
||||
logRequestParams: null,
|
||||
logResponseData: null,
|
||||
assets: {
|
||||
folder: "public",
|
||||
options: {},
|
||||
},
|
||||
|
||||
// Mapping policy setting. More info: https://moleculer.services/docs/0.14/moleculer-web.html#Mapping-policy
|
||||
mappingPolicy: "all", // Available values: "all", "restrict"
|
||||
|
||||
// Enable/disable logging
|
||||
logging: true,
|
||||
},
|
||||
],
|
||||
|
||||
// Do not log client side errors (does not log an error response when the error.code is 400<=X<500)
|
||||
log4XXResponses: false,
|
||||
// Logging the request parameters. Set to any log level to enable it. E.g. "info"
|
||||
logRequestParams: null,
|
||||
// Logging the response data. Set to any log level to enable it. E.g. "info"
|
||||
logResponseData: null,
|
||||
methods: {
|
||||
/**
|
||||
* Authenticate the request. It checks the `Authorization` token value in the request header.
|
||||
* Check the token value & resolve the user by the token.
|
||||
* The resolved user will be available in `ctx.meta.user`
|
||||
*
|
||||
* PLEASE NOTE, IT'S JUST AN EXAMPLE IMPLEMENTATION. DO NOT USE IN PRODUCTION!
|
||||
*
|
||||
* @param {Context} ctx
|
||||
* @param {any} route
|
||||
* @param {IncomingMessage} req
|
||||
* @returns {Promise}
|
||||
|
||||
// Serve assets from "public" folder. More info: https://moleculer.services/docs/0.14/moleculer-web.html#Serve-static-files
|
||||
assets: {
|
||||
folder: "public",
|
||||
async authenticate (ctx: Context, route: any, req: IncomingMessage): Promise < any > => {
|
||||
// Read the token from header
|
||||
const auth = req.headers.authorization;
|
||||
|
||||
// Options to `server-static` module
|
||||
options: {},
|
||||
},
|
||||
},
|
||||
if (auth && auth.startsWith("Bearer")) {
|
||||
const token = auth.slice(7);
|
||||
|
||||
methods: {
|
||||
/**
|
||||
* Authenticate the request. It check the `Authorization` token value in the request header.
|
||||
* Check the token value & resolve the user by the token.
|
||||
* The resolved user will be available in `ctx.meta.user`
|
||||
*
|
||||
* PLEASE NOTE, IT'S JUST AN EXAMPLE IMPLEMENTATION. DO NOT USE IN PRODUCTION!
|
||||
*/
|
||||
authenticate(
|
||||
ctx: Context,
|
||||
route: Route,
|
||||
req: IncomingRequest,
|
||||
): Record<string, unknown> | null {
|
||||
// Read the token from header
|
||||
const auth = req.headers.authorization;
|
||||
// Check the token. Tip: call a service which verify the token. E.g. `accounts.resolveToken`
|
||||
if (token === "123456") {
|
||||
// Returns the resolved user. It will be set to the `ctx.meta.user`
|
||||
return {
|
||||
id: 1,
|
||||
name: "John Doe",
|
||||
};
|
||||
|
||||
if (auth && auth.startsWith("Bearer")) {
|
||||
const token = auth.slice(7);
|
||||
} else {
|
||||
// Invalid token
|
||||
throw new ApiGateway.Errors.UnAuthorizedError(ApiGateway.Errors.ERR_INVALID_TOKEN, {
|
||||
error: "Invalid Token",
|
||||
});
|
||||
}
|
||||
|
||||
// Check the token. Tip: call a service which verify the token. E.g. `accounts.resolveToken`
|
||||
if (token === "123456") {
|
||||
// Returns the resolved user. It will be set to the `ctx.meta.user`
|
||||
return { id: 1, name: "John Doe" };
|
||||
}
|
||||
// Invalid token
|
||||
throw new ApiGateway.Errors.UnAuthorizedError(
|
||||
ApiGateway.Errors.ERR_INVALID_TOKEN,
|
||||
null,
|
||||
);
|
||||
} else {
|
||||
// No token. Throw an error or do nothing if anonymous access is allowed.
|
||||
// throw new E.UnAuthorizedError(E.ERR_NO_TOKEN);
|
||||
return null;
|
||||
}
|
||||
},
|
||||
} else {
|
||||
// No token. Throw an error or do nothing if anonymous access is allowed.
|
||||
// Throw new E.UnAuthorizedError(E.ERR_NO_TOKEN);
|
||||
return null;
|
||||
}
|
||||
},
|
||||
*/
|
||||
/**
|
||||
* Authorize the request. Check that the authenticated user has right to access the resource.
|
||||
*
|
||||
* PLEASE NOTE, IT'S JUST AN EXAMPLE IMPLEMENTATION. DO NOT USE IN PRODUCTION!
|
||||
*
|
||||
* @param {Context} ctx
|
||||
* @param {Object} route
|
||||
* @param {IncomingMessage} req
|
||||
* @returns {Promise}
|
||||
|
||||
/**
|
||||
* Authorize the request. Check that the authenticated user has right to access the resource.
|
||||
*
|
||||
* PLEASE NOTE, IT'S JUST AN EXAMPLE IMPLEMENTATION. DO NOT USE IN PRODUCTION!
|
||||
*/
|
||||
authorize(ctx: Context<null, Meta>, route: Route, req: IncomingRequest) {
|
||||
// Get the authenticated user.
|
||||
const { user } = ctx.meta;
|
||||
async authorize (ctx: Context < any, {
|
||||
user: string;
|
||||
} > , route: Record<string, undefined>, req: IncomingMessage): Promise < any > => {
|
||||
// Get the authenticated user.
|
||||
const user = ctx.meta.user;
|
||||
|
||||
// It check the `auth` property in action schema.
|
||||
if (req.$action.auth === "required" && !user) {
|
||||
throw new ApiGateway.Errors.UnAuthorizedError("NO_RIGHTS", null);
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default ApiService;
|
||||
// It check the `auth` property in action schema.
|
||||
// @ts-ignore
|
||||
if (req.$action.auth === "required" && !user) {
|
||||
throw new ApiGateway.Errors.UnAuthorizedError("NO_RIGHTS", {
|
||||
error: "Unauthorized",
|
||||
});
|
||||
}
|
||||
},
|
||||
*/
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
"use strict";
|
||||
import { Context, Service, ServiceBroker, ServiceSchema, Errors } from "moleculer";
|
||||
import { qBittorrentClient} from "@robertklep/qbittorrent";
|
||||
import { qBittorrentClient } from "@robertklep/qbittorrent";
|
||||
const { MoleculerError } = require("moleculer").Errors;
|
||||
|
||||
export default class QBittorrentService extends Service {
|
||||
// @ts-ignore
|
||||
@@ -14,23 +15,25 @@ export default class QBittorrentService extends Service {
|
||||
mixins: [],
|
||||
hooks: {},
|
||||
actions: {
|
||||
connect: {
|
||||
rest: "POST /connect",
|
||||
handler: async (ctx: Context<{}>) => {
|
||||
const torrentClient = new qBittorrentClient("http://192.168.1.183:8089", "admin", "adminadmin");
|
||||
const info = await torrentClient.torrents.info();
|
||||
|
||||
return { foo: info };
|
||||
},
|
||||
},
|
||||
getList : {
|
||||
rest: "GET /getList",
|
||||
getList: {
|
||||
rest: "GET /getTorrents",
|
||||
handler: async (ctx: Context<{}>) => {
|
||||
|
||||
return await this.torrentClient.torrents.info()
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {},
|
||||
}, methods: {},
|
||||
async started(): Promise<any> {
|
||||
try {
|
||||
this.torrentClient = new qBittorrentClient("http://192.168.1.183:8089", "admin", "adminadmin");
|
||||
|
||||
} catch (err) {
|
||||
throw new MoleculerError(err, 500, "QBITTORRENT_CONNECTION_ERROR", {
|
||||
data: err,
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user