diff --git a/package.json b/package.json
index 141154f..d8212b6 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@odit/lfk-document-server",
- "version": "0.3.0",
+ "version": "0.3.1",
"description": "The document generation server for the LfK! runner system. This generates certificates, sponsoring aggreements and more",
"main": "src/app.ts",
"scripts": {
diff --git a/src/apispec.ts b/src/apispec.ts
index 9aa3018..6860264 100644
--- a/src/apispec.ts
+++ b/src/apispec.ts
@@ -1,33 +1,33 @@
-import { MetadataArgsStorage } from 'routing-controllers';
-import { routingControllersToSpec } from 'routing-controllers-openapi';
-import { config } from './config';
-
-/**
- * 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,
- {},
- {
- components: {
- schemas,
- "securitySchemes": {
- "AuthToken": {
- "type": "apiKey",
- "in": "query",
- "name": "key",
- description: "A simple api key. See the README's env section for more details."
- }
- }
- },
- info: {
- description: "The the API for the LfK! document server.",
- title: "LfK! document server API",
- version: config.version
- },
- }
- );
+import { MetadataArgsStorage } from 'routing-controllers';
+import { routingControllersToSpec } from 'routing-controllers-openapi';
+import { config } from './config';
+
+/**
+ * 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,
+ {},
+ {
+ components: {
+ schemas,
+ "securitySchemes": {
+ "AuthToken": {
+ "type": "apiKey",
+ "in": "query",
+ "name": "key",
+ description: "A simple api key. See the README's env section for more details."
+ }
+ }
+ },
+ info: {
+ description: "The the API for the LfK! document server.",
+ title: "LfK! document server API",
+ version: config.version
+ },
+ }
+ );
}
\ No newline at end of file
diff --git a/src/app.ts b/src/app.ts
index 78846f3..ee2396b 100644
--- a/src/app.ts
+++ b/src/app.ts
@@ -1,31 +1,31 @@
-import consola from "consola";
-import "reflect-metadata";
-import { createExpressServer } from "routing-controllers";
-import { config, e as errors } from './config';
-import loaders from "./loaders/index";
-import AuthChecker from './middlewares/AuthChecker';
-import { ErrorHandler } from './middlewares/ErrorHandler';
-
-const CONTROLLERS_FILE_EXTENSION = process.env.NODE_ENV === 'production' ? 'js' : 'ts';
-const app = createExpressServer({
- middlewares: [ErrorHandler],
- authorizationChecker: AuthChecker,
- development: config.development,
- cors: true,
- controllers: [`${__dirname}/controllers/*.${CONTROLLERS_FILE_EXTENSION}`],
-});
-
-async function main() {
- await loaders(app);
- app.listen(config.internal_port, () => {
- consola.success(
- `⚡️[server]: Server is running at http://localhost:${config.internal_port}`
- );
- });
-}
-if (errors === 0) {
- main();
-} else {
- consola.error("error");
- // something's wrong
-}
+import consola from "consola";
+import "reflect-metadata";
+import { createExpressServer } from "routing-controllers";
+import { config, e as errors } from './config';
+import loaders from "./loaders/index";
+import AuthChecker from './middlewares/AuthChecker';
+import { ErrorHandler } from './middlewares/ErrorHandler';
+
+const CONTROLLERS_FILE_EXTENSION = process.env.NODE_ENV === 'production' ? 'js' : 'ts';
+const app = createExpressServer({
+ middlewares: [ErrorHandler],
+ authorizationChecker: AuthChecker,
+ development: config.development,
+ cors: true,
+ controllers: [`${__dirname}/controllers/*.${CONTROLLERS_FILE_EXTENSION}`],
+});
+
+async function main() {
+ await loaders(app);
+ app.listen(config.internal_port, () => {
+ consola.success(
+ `⚡️[server]: Server is running at http://localhost:${config.internal_port}`
+ );
+ });
+}
+if (errors === 0) {
+ main();
+} else {
+ consola.error("error");
+ // something's wrong
+}
diff --git a/src/config.ts b/src/config.ts
index e7da417..bded138 100644
--- a/src/config.ts
+++ b/src/config.ts
@@ -1,52 +1,52 @@
-import consola from "consola";
-import { config as configDotenv } from 'dotenv';
-
-configDotenv();
-export const config = {
- internal_port: parseInt(process.env.APP_PORT) || 4010,
- development: process.env.NODE_ENV === "production",
- version: process.env.VERSION || require('../package.json').version,
- eventname: process.env.EVENT_NAME || "Please set the event name",
- currency_symbol: process.env.CURRENCY_SYMBOL || "€",
- sponsoring_receipt_minimum_amount: process.env.SPONSORING_RECEIPT_MINIMUM_AMOUNT || "10",
- codeformat: process.env.CODEFORMAT || "qrcode",
- sponor_logos: getSponsorLogos(),
- api_key: getApiKey(),
-}
-let errors = 0
-if (typeof config.internal_port !== "number") {
- errors++
-}
-if (typeof config.development !== "boolean") {
- errors++
-}
-function getSponsorLogos(): string[] {
- try {
- const logos = JSON.parse(process.env.SPONOR_LOGOS);
- if (!Array.isArray(logos)) { throw new Error("Not an array.") }
- return logos;
- } catch (error) {
- return ["data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+P+/HgAFhAJ/wlseKgAAAABJRU5ErkJggg=="];
- }
-}
-
-function getApiKey(): string {
- const key = process.env.API_KEY;
- if (!key) {
- consola.info("No API key set - generating a random one...");
- let result = '';
- const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
- const charactersLength = characters.length;
- for (var i = 0; i < 64; i++) {
- result += characters.charAt(Math.floor(Math.random() * charactersLength));
- }
- consola.info(`API KEY: ${result}`)
- return result;
- }
- if (key.length < 64) {
- consola.error(`API key is too short - minimum: 64, current: ${key.length}`)
- throw new Error("API_KEY too short.")
- }
- return key
-}
+import consola from "consola";
+import { config as configDotenv } from 'dotenv';
+
+configDotenv();
+export const config = {
+ internal_port: parseInt(process.env.APP_PORT) || 4010,
+ development: process.env.NODE_ENV === "production",
+ version: process.env.VERSION || require('../package.json').version,
+ eventname: process.env.EVENT_NAME || "Please set the event name",
+ currency_symbol: process.env.CURRENCY_SYMBOL || "€",
+ sponsoring_receipt_minimum_amount: process.env.SPONSORING_RECEIPT_MINIMUM_AMOUNT || "10",
+ codeformat: process.env.CODEFORMAT || "qrcode",
+ sponor_logos: getSponsorLogos(),
+ api_key: getApiKey(),
+}
+let errors = 0
+if (typeof config.internal_port !== "number") {
+ errors++
+}
+if (typeof config.development !== "boolean") {
+ errors++
+}
+function getSponsorLogos(): string[] {
+ try {
+ const logos = JSON.parse(process.env.SPONOR_LOGOS);
+ if (!Array.isArray(logos)) { throw new Error("Not an array.") }
+ return logos;
+ } catch (error) {
+ return ["data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+P+/HgAFhAJ/wlseKgAAAABJRU5ErkJggg=="];
+ }
+}
+
+function getApiKey(): string {
+ const key = process.env.API_KEY;
+ if (!key) {
+ consola.info("No API key set - generating a random one...");
+ let result = '';
+ const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
+ const charactersLength = characters.length;
+ for (var i = 0; i < 64; i++) {
+ result += characters.charAt(Math.floor(Math.random() * charactersLength));
+ }
+ consola.info(`API KEY: ${result}`)
+ return result;
+ }
+ if (key.length < 64) {
+ consola.error(`API key is too short - minimum: 64, current: ${key.length}`)
+ throw new Error("API_KEY too short.")
+ }
+ return key
+}
export let e = errors
\ No newline at end of file
diff --git a/src/controllers/PdfController.ts b/src/controllers/PdfController.ts
index 3e82693..f3a1009 100644
--- a/src/controllers/PdfController.ts
+++ b/src/controllers/PdfController.ts
@@ -1,48 +1,48 @@
-import { Authorized, Body, JsonController, Post, QueryParam, Res } from 'routing-controllers';
-import { OpenAPI } from 'routing-controllers-openapi';
-import { Runner } from '../models/Runner';
-import { RunnerCard } from '../models/RunnerCard';
-import { PdfCreator } from '../PdfCreator';
-
-/**
- * The pdf controller handels all endpoints concerning pdf generation.
- * It therefore is the hearth of the document-generation server's endpoints.
- * All endpoints have to accept a locale query-param to support i18n.
- */
-@JsonController()
-@Authorized()
-@OpenAPI({ security: [{ "AuthToken": [] }] })
-export class PdfController {
- private pdf: PdfCreator = new PdfCreator();
- private initialized: boolean = false;
-
- @Post('/contracts')
- @OpenAPI({ description: "Generate Sponsoring contract pdfs from runner objects.
You can choose your prefered locale by passing the 'locale' query-param.
If you provide more than 100 runenrs this could take a moment or two (we tested up to 1000 runners in about 70sec so far)." })
- async generateContracts(@Body({ validate: true, options: { limit: "500mb" } }) runners: Runner | Runner[], @Res() res: any, @QueryParam("locale") locale: string, @QueryParam("codeformat") codeformat: string) {
- if (!this.initialized) {
- await this.pdf.init();
- this.initialized = true;
- }
- if (!Array.isArray(runners)) {
- runners = [runners];
- }
- const contracts = await this.pdf.generateSponsoringContract(runners, locale, codeformat);
- res.setHeader('content-type', 'application/pdf');
- return contracts;
- }
-
- @Post('/cards')
- @OpenAPI({ description: "Generate runner card pdfs from runner card objects.
You can choose your prefered locale by passing the 'locale' query-param." })
- async generateCards(@Body({ validate: true, options: { limit: "500mb" } }) cards: RunnerCard | RunnerCard[], @Res() res: any, @QueryParam("locale") locale: string) {
- if (!this.initialized) {
- await this.pdf.init();
- this.initialized = true;
- }
- if (!Array.isArray(cards)) {
- cards = [cards];
- }
- const contracts = await this.pdf.generateRunnerCards(cards, locale);
- res.setHeader('content-type', 'application/pdf');
- return contracts;
- }
-}
+import { Authorized, Body, JsonController, Post, QueryParam, Res } from 'routing-controllers';
+import { OpenAPI } from 'routing-controllers-openapi';
+import { Runner } from '../models/Runner';
+import { RunnerCard } from '../models/RunnerCard';
+import { PdfCreator } from '../PdfCreator';
+
+/**
+ * The pdf controller handels all endpoints concerning pdf generation.
+ * It therefore is the hearth of the document-generation server's endpoints.
+ * All endpoints have to accept a locale query-param to support i18n.
+ */
+@JsonController()
+@Authorized()
+@OpenAPI({ security: [{ "AuthToken": [] }] })
+export class PdfController {
+ private pdf: PdfCreator = new PdfCreator();
+ private initialized: boolean = false;
+
+ @Post('/contracts')
+ @OpenAPI({ description: "Generate Sponsoring contract pdfs from runner objects.
You can choose your prefered locale by passing the 'locale' query-param.
If you provide more than 100 runenrs this could take a moment or two (we tested up to 1000 runners in about 70sec so far)." })
+ async generateContracts(@Body({ validate: true, options: { limit: "500mb" } }) runners: Runner | Runner[], @Res() res: any, @QueryParam("locale") locale: string, @QueryParam("codeformat") codeformat: string) {
+ if (!this.initialized) {
+ await this.pdf.init();
+ this.initialized = true;
+ }
+ if (!Array.isArray(runners)) {
+ runners = [runners];
+ }
+ const contracts = await this.pdf.generateSponsoringContract(runners, locale, codeformat);
+ res.setHeader('content-type', 'application/pdf');
+ return contracts;
+ }
+
+ @Post('/cards')
+ @OpenAPI({ description: "Generate runner card pdfs from runner card objects.
You can choose your prefered locale by passing the 'locale' query-param." })
+ async generateCards(@Body({ validate: true, options: { limit: "500mb" } }) cards: RunnerCard | RunnerCard[], @Res() res: any, @QueryParam("locale") locale: string) {
+ if (!this.initialized) {
+ await this.pdf.init();
+ this.initialized = true;
+ }
+ if (!Array.isArray(cards)) {
+ cards = [cards];
+ }
+ const contracts = await this.pdf.generateRunnerCards(cards, locale);
+ res.setHeader('content-type', 'application/pdf');
+ return contracts;
+ }
+}
diff --git a/src/middlewares/AuthChecker.ts b/src/middlewares/AuthChecker.ts
index e4ede50..19160b3 100644
--- a/src/middlewares/AuthChecker.ts
+++ b/src/middlewares/AuthChecker.ts
@@ -1,14 +1,14 @@
-import { Action } from "routing-controllers";
-import { config } from '../config';
-
-/**
- * Handles authentication via jwt's (Bearer authorization header) for all api endpoints using the @Authorized decorator.
- * @param action Routing-Controllers action object that provides request and response objects among other stuff.
- * @param permissions The permissions that the endpoint using @Authorized requires.
- */
-const AuthChecker = async (action: Action) => {
- const provided_token = action.request.query.key;
- return provided_token == config.api_key;
-}
-
+import { Action } from "routing-controllers";
+import { config } from '../config';
+
+/**
+ * Handles authentication via jwt's (Bearer authorization header) for all api endpoints using the @Authorized decorator.
+ * @param action Routing-Controllers action object that provides request and response objects among other stuff.
+ * @param permissions The permissions that the endpoint using @Authorized requires.
+ */
+const AuthChecker = async (action: Action) => {
+ const provided_token = action.request.query.key;
+ return provided_token == config.api_key;
+}
+
export default AuthChecker
\ No newline at end of file