feat: Passwordless cross-device authentication

- Arkitektur: docs/auth/passwordless-architecture.md
- Backend: iom/quixzoom-auth-service/ (FastAPI + Redis)
- Webb: quixzoom-market-pages/se/login/ (QR-kod + polling)
- App: iom/quixzoom-app/src/features/auth/ (push + deep links)

Flöde: QR-kod → app-godkännande → webb-inloggad
This commit is contained in:
Bernt
2026-07-07 07:11:50 +00:00
parent 4aa984ad74
commit 6989a98d75
61843 changed files with 5491611 additions and 872231 deletions
+8
View File
@@ -0,0 +1,8 @@
import { RequestHandler } from 'express-serve-static-core';
import { JobCleanStatus } from '../@types/app';
declare type RequestParams = {
queueName: string;
queueStatus: JobCleanStatus;
};
export declare const cleanAll: RequestHandler<RequestParams>;
export {};
+23
View File
@@ -0,0 +1,23 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.cleanAll = void 0;
const cleanAll = async (req, res) => {
const { queueName, queueStatus } = req.params;
const { bullBoardQueues } = req.app.locals;
const GRACE_TIME_MS = 5000;
const { queue } = bullBoardQueues[queueName];
if (!queue) {
return res.status(404).send({
error: 'Queue not found',
});
}
else if (queue.readOnlyMode) {
return res.status(405).send({
error: 'Method not allowed on read only queue',
});
}
await queue.clean(queueStatus, GRACE_TIME_MS);
return res.sendStatus(200);
};
exports.cleanAll = cleanAll;
//# sourceMappingURL=cleanAll.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"cleanAll.js","sourceRoot":"","sources":["../../src/routes/cleanAll.ts"],"names":[],"mappings":";;;AAQO,MAAM,QAAQ,GAAkC,KAAK,EAC1D,GAAY,EACZ,GAAa,EACb,EAAE;IACF,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,GAAG,GAAG,CAAC,MAAM,CAAA;IAC7C,MAAM,EAAE,eAAe,EAAE,GAAG,GAAG,CAAC,GAAG,CAAC,MAEnC,CAAA;IAED,MAAM,aAAa,GAAG,IAAI,CAAA;IAE1B,MAAM,EAAE,KAAK,EAAE,GAAG,eAAe,CAAC,SAAS,CAAC,CAAA;IAC5C,IAAI,CAAC,KAAK,EAAE;QACV,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;YAC1B,KAAK,EAAE,iBAAiB;SACzB,CAAC,CAAA;KACH;SAAM,IAAI,KAAK,CAAC,YAAY,EAAE;QAC7B,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;YAC1B,KAAK,EAAE,uCAAuC;SAC/C,CAAC,CAAA;KACH;IAED,MAAM,KAAK,CAAC,KAAK,CAAC,WAAkB,EAAE,aAAa,CAAC,CAAA;IAEpD,OAAO,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAA;AAC5B,CAAC,CAAA;AAzBY,QAAA,QAAQ,YAyBpB"}
+2
View File
@@ -0,0 +1,2 @@
import { RequestHandler } from 'express-serve-static-core';
export declare const cleanJob: RequestHandler;
+28
View File
@@ -0,0 +1,28 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.cleanJob = void 0;
const cleanJob = async (req, res) => {
const { bullBoardQueues } = req.app.locals;
const { queueName, id } = req.params;
const { queue } = bullBoardQueues[queueName];
if (!queue) {
return res.status(404).send({
error: 'Queue not found',
});
}
else if (queue.readOnlyMode) {
return res.status(405).send({
error: 'Method not allowed on read only queue',
});
}
const job = await queue.getJob(id);
if (!job) {
return res.status(404).send({
error: 'Job not found',
});
}
await job.remove();
return res.sendStatus(204);
};
exports.cleanJob = cleanJob;
//# sourceMappingURL=cleanJob.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"cleanJob.js","sourceRoot":"","sources":["../../src/routes/cleanJob.ts"],"names":[],"mappings":";;;AAGO,MAAM,QAAQ,GAAmB,KAAK,EAAE,GAAY,EAAE,GAAa,EAAE,EAAE;IAC5E,MAAM,EAAE,eAAe,EAAE,GAAG,GAAG,CAAC,GAAG,CAAC,MAEnC,CAAA;IACD,MAAM,EAAE,SAAS,EAAE,EAAE,EAAE,GAAG,GAAG,CAAC,MAAM,CAAA;IACpC,MAAM,EAAE,KAAK,EAAE,GAAG,eAAe,CAAC,SAAS,CAAC,CAAA;IAE5C,IAAI,CAAC,KAAK,EAAE;QACV,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;YAC1B,KAAK,EAAE,iBAAiB;SACzB,CAAC,CAAA;KACH;SAAM,IAAI,KAAK,CAAC,YAAY,EAAE;QAC7B,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;YAC1B,KAAK,EAAE,uCAAuC;SAC/C,CAAC,CAAA;KACH;IAED,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;IAElC,IAAI,CAAC,GAAG,EAAE;QACR,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;YAC1B,KAAK,EAAE,eAAe;SACvB,CAAC,CAAA;KACH;IAED,MAAM,GAAG,CAAC,MAAM,EAAE,CAAA;IAElB,OAAO,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAA;AAC5B,CAAC,CAAA;AA5BY,QAAA,QAAQ,YA4BpB"}
+2
View File
@@ -0,0 +1,2 @@
import { Request, Response } from 'express-serve-static-core';
export declare function errorHandler(err: Error, _req: Request, res: Response, _next: any): void;
+12
View File
@@ -0,0 +1,12 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.errorHandler = void 0;
function errorHandler(err, _req, res, _next) {
res.status(500).send({
error: 'Queue error',
message: err.message,
details: err.stack,
});
}
exports.errorHandler = errorHandler;
//# sourceMappingURL=errorHandler.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"errorHandler.js","sourceRoot":"","sources":["../../src/routes/errorHandler.ts"],"names":[],"mappings":";;;AAEA,SAAgB,YAAY,CAC1B,GAAU,EACV,IAAa,EACb,GAAa,EACb,KAAU;IAEV,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;QACnB,KAAK,EAAE,aAAa;QACpB,OAAO,EAAE,GAAG,CAAC,OAAO;QACpB,OAAO,EAAE,GAAG,CAAC,KAAK;KACnB,CAAC,CAAA;AACJ,CAAC;AAXD,oCAWC"}
+2
View File
@@ -0,0 +1,2 @@
import { RequestHandler } from 'express-serve-static-core';
export declare const entryPoint: RequestHandler;
+11
View File
@@ -0,0 +1,11 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.entryPoint = void 0;
const entryPoint = (req, res) => {
const basePath = req.proxyUrl || req.baseUrl;
res.render('index', {
basePath,
});
};
exports.entryPoint = entryPoint;
//# sourceMappingURL=index.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/routes/index.ts"],"names":[],"mappings":";;;AAEO,MAAM,UAAU,GAAmB,CAAC,GAAY,EAAE,GAAa,EAAE,EAAE;IACxE,MAAM,QAAQ,GAAI,GAAW,CAAC,QAAQ,IAAI,GAAG,CAAC,OAAO,CAAA;IAErD,GAAG,CAAC,MAAM,CAAC,OAAO,EAAE;QAClB,QAAQ;KACT,CAAC,CAAA;AACJ,CAAC,CAAA;AANY,QAAA,UAAU,cAMtB"}
+2
View File
@@ -0,0 +1,2 @@
import { RequestHandler } from 'express-serve-static-core';
export declare const jobLogs: RequestHandler;
+23
View File
@@ -0,0 +1,23 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.jobLogs = void 0;
const jobLogs = async (req, res) => {
const { bullBoardQueues } = req.app.locals;
const { queueName, id } = req.params;
const { queue } = bullBoardQueues[queueName];
if (!queue) {
return res.status(404).send({
error: 'Queue not found',
});
}
const job = await queue.getJob(id);
if (!job) {
return res.status(404).send({
error: 'Job not found',
});
}
const logs = await queue.getJobLogs(id);
return res.json(logs);
};
exports.jobLogs = jobLogs;
//# sourceMappingURL=jobLogs.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"jobLogs.js","sourceRoot":"","sources":["../../src/routes/jobLogs.ts"],"names":[],"mappings":";;;AAGO,MAAM,OAAO,GAAmB,KAAK,EAAE,GAAY,EAAE,GAAa,EAAE,EAAE;IAC3E,MAAM,EAAE,eAAe,EAAE,GAAG,GAAG,CAAC,GAAG,CAAC,MAEnC,CAAA;IACD,MAAM,EAAE,SAAS,EAAE,EAAE,EAAE,GAAG,GAAG,CAAC,MAAM,CAAA;IACpC,MAAM,EAAE,KAAK,EAAE,GAAG,eAAe,CAAC,SAAS,CAAC,CAAA;IAE5C,IAAI,CAAC,KAAK,EAAE;QACV,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;YAC1B,KAAK,EAAE,iBAAiB;SACzB,CAAC,CAAA;KACH;IAED,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;IAElC,IAAI,CAAC,GAAG,EAAE;QACR,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;YAC1B,KAAK,EAAE,eAAe;SACvB,CAAC,CAAA;KACH;IAED,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC,CAAA;IAEvC,OAAO,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACvB,CAAC,CAAA;AAxBY,QAAA,OAAO,WAwBnB"}
+2
View File
@@ -0,0 +1,2 @@
import { RequestHandler } from 'express-serve-static-core';
export declare const promoteJob: RequestHandler;
+28
View File
@@ -0,0 +1,28 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.promoteJob = void 0;
const promoteJob = async (req, res) => {
const { bullBoardQueues } = req.app.locals;
const { queueName, id } = req.params;
const { queue } = bullBoardQueues[queueName];
if (!queue) {
return res.status(404).send({
error: 'Queue not found',
});
}
else if (queue.readOnlyMode) {
return res.status(405).send({
error: 'Method not allowed on read only queue',
});
}
const job = await queue.getJob(id);
if (!job) {
return res.status(404).send({
error: 'Job not found',
});
}
await job.promote();
return res.sendStatus(204);
};
exports.promoteJob = promoteJob;
//# sourceMappingURL=promoteJob.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"promoteJob.js","sourceRoot":"","sources":["../../src/routes/promoteJob.ts"],"names":[],"mappings":";;;AAGO,MAAM,UAAU,GAAmB,KAAK,EAC7C,GAAY,EACZ,GAAa,EACb,EAAE;IACF,MAAM,EAAE,eAAe,EAAE,GAAG,GAAG,CAAC,GAAG,CAAC,MAEnC,CAAA;IACD,MAAM,EAAE,SAAS,EAAE,EAAE,EAAE,GAAG,GAAG,CAAC,MAAM,CAAA;IACpC,MAAM,EAAE,KAAK,EAAE,GAAG,eAAe,CAAC,SAAS,CAAC,CAAA;IAE5C,IAAI,CAAC,KAAK,EAAE;QACV,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;YAC1B,KAAK,EAAE,iBAAiB;SACzB,CAAC,CAAA;KACH;SAAM,IAAI,KAAK,CAAC,YAAY,EAAE;QAC7B,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;YAC1B,KAAK,EAAE,uCAAuC;SAC/C,CAAC,CAAA;KACH;IAED,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;IAElC,IAAI,CAAC,GAAG,EAAE;QACR,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;YAC1B,KAAK,EAAE,eAAe;SACvB,CAAC,CAAA;KACH;IAED,MAAM,GAAG,CAAC,OAAO,EAAE,CAAA;IAEnB,OAAO,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAA;AAC5B,CAAC,CAAA;AA/BY,QAAA,UAAU,cA+BtB"}
+2
View File
@@ -0,0 +1,2 @@
import { RequestHandler } from 'express-serve-static-core';
export declare const queuesHandler: RequestHandler;
+83
View File
@@ -0,0 +1,83 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.queuesHandler = void 0;
const redis_info_1 = require("redis-info");
const metrics = [
'redis_version',
'used_memory',
'mem_fragmentation_ratio',
'connected_clients',
'blocked_clients',
];
const getStats = async ({ queue, }) => {
const redisClient = await queue.getClient();
const redisInfoRaw = await redisClient.info();
const redisInfo = redis_info_1.parse(redisInfoRaw);
const validMetrics = metrics.reduce((acc, metric) => {
if (redisInfo[metric]) {
acc[metric] = redisInfo[metric];
}
return acc;
}, {});
validMetrics.total_system_memory =
redisInfo.total_system_memory || redisInfo.maxmemory;
return validMetrics;
};
const formatJob = (job, queue) => {
const jobProps = job.toJSON();
return {
id: jobProps.id,
timestamp: jobProps.timestamp,
processedOn: jobProps.processedOn,
finishedOn: jobProps.finishedOn,
progress: jobProps.progress,
attempts: jobProps.attemptsMade,
delay: job.opts.delay,
failedReason: jobProps.failedReason,
stacktrace: jobProps.stacktrace ? jobProps.stacktrace.filter(Boolean) : [],
opts: jobProps.opts,
data: queue.format('data', jobProps.data),
name: jobProps.name,
returnValue: queue.format('returnValue', jobProps.returnvalue),
};
};
const statuses = [
'active',
'completed',
'delayed',
'failed',
'paused',
'waiting',
];
const getDataForQueues = async (bullBoardQueues, req) => {
const query = req.query || {};
const pairs = Object.entries(bullBoardQueues);
if (pairs.length == 0) {
return {
stats: {},
queues: [],
};
}
const queues = await Promise.all(pairs.map(async ([name, { queue }]) => {
const counts = await queue.getJobCounts(...statuses);
const status = query[name] === 'latest' ? statuses : query[name];
const jobs = await queue.getJobs(status, 0, 10);
return {
name,
counts: counts,
jobs: jobs.filter(Boolean).map((job) => formatJob(job, queue)),
readOnlyMode: queue.readOnlyMode,
};
}));
const stats = await getStats(pairs[0][1]);
return {
stats,
queues,
};
};
const queuesHandler = async (req, res) => {
const { bullBoardQueues } = req.app.locals;
res.json(await getDataForQueues(bullBoardQueues, req));
};
exports.queuesHandler = queuesHandler;
//# sourceMappingURL=queues.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"queues.js","sourceRoot":"","sources":["../../src/routes/queues.ts"],"names":[],"mappings":";;;AAGA,2CAAoD;AASpD,MAAM,OAAO,GAAiB;IAC5B,eAAe;IACf,aAAa;IACb,yBAAyB;IACzB,mBAAmB;IACnB,iBAAiB;CAClB,CAAA;AAED,MAAM,QAAQ,GAAG,KAAK,EAAE,EACtB,KAAK,GACc,EAA6B,EAAE;IAClD,MAAM,WAAW,GAAG,MAAM,KAAK,CAAC,SAAS,EAAE,CAAA;IAC3C,MAAM,YAAY,GAAG,MAAM,WAAW,CAAC,IAAI,EAAE,CAAA;IAC7C,MAAM,SAAS,GAAG,kBAAc,CAAC,YAAY,CAAC,CAAA;IAE9C,MAAM,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE;QAClD,IAAI,SAAS,CAAC,MAAM,CAAC,EAAE;YACrB,GAAG,CAAC,MAAM,CAAC,GAAG,SAAS,CAAC,MAAM,CAAC,CAAA;SAChC;QAED,OAAO,GAAG,CAAA;IACZ,CAAC,EAAE,EAAgC,CAAC,CAAA;IAEpC,YAAY,CAAC,mBAAmB;QAC9B,SAAS,CAAC,mBAAmB,IAAI,SAAS,CAAC,SAAS,CAAA;IAEtD,OAAO,YAAY,CAAA;AACrB,CAAC,CAAA;AAED,MAAM,SAAS,GAAG,CAAC,GAAgB,EAAE,KAAmB,EAAc,EAAE;IACtE,MAAM,QAAQ,GAAG,GAAG,CAAC,MAAM,EAAE,CAAA;IAE7B,OAAO;QACL,EAAE,EAAE,QAAQ,CAAC,EAAE;QACf,SAAS,EAAE,QAAQ,CAAC,SAAS;QAC7B,WAAW,EAAE,QAAQ,CAAC,WAAW;QACjC,UAAU,EAAE,QAAQ,CAAC,UAAU;QAC/B,QAAQ,EAAE,QAAQ,CAAC,QAAQ;QAC3B,QAAQ,EAAE,QAAQ,CAAC,YAAY;QAC/B,KAAK,EAAE,GAAG,CAAC,IAAI,CAAC,KAAK;QACrB,YAAY,EAAE,QAAQ,CAAC,YAAY;QACnC,UAAU,EAAE,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE;QAC1E,IAAI,EAAE,QAAQ,CAAC,IAAI;QACnB,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,IAAI,CAAC;QACzC,IAAI,EAAE,QAAQ,CAAC,IAAI;QACnB,WAAW,EAAE,KAAK,CAAC,MAAM,CAAC,aAAa,EAAE,QAAQ,CAAC,WAAW,CAAC;KAC/D,CAAA;AACH,CAAC,CAAA;AAED,MAAM,QAAQ,GAAgB;IAC5B,QAAQ;IACR,WAAW;IACX,SAAS;IACT,QAAQ;IACR,QAAQ;IACR,SAAS;CACV,CAAA;AAED,MAAM,gBAAgB,GAAG,KAAK,EAC5B,eAAoC,EACpC,GAAY,EACY,EAAE;IAC1B,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,IAAI,EAAE,CAAA;IAC7B,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,CAAA;IAE7C,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC,EAAE;QACrB,OAAO;YACL,KAAK,EAAE,EAAE;YACT,MAAM,EAAE,EAAE;SACX,CAAA;KACF;IAED,MAAM,MAAM,GAAmB,MAAM,OAAO,CAAC,GAAG,CAC9C,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QACpC,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,YAAY,CAAC,GAAG,QAAQ,CAAC,CAAA;QACpD,MAAM,MAAM,GACV,KAAK,CAAC,IAAI,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAE,KAAK,CAAC,IAAI,CAAiB,CAAA;QACpE,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC,CAAA;QAE/C,OAAO;YACL,IAAI;YACJ,MAAM,EAAE,MAAgC;YACxC,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;YAC9D,YAAY,EAAE,KAAK,CAAC,YAAY;SACjC,CAAA;IACH,CAAC,CAAC,CACH,CAAA;IAED,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IAEzC,OAAO;QACL,KAAK;QACL,MAAM;KACP,CAAA;AACH,CAAC,CAAA;AAEM,MAAM,aAAa,GAAmB,KAAK,EAChD,GAAY,EACZ,GAAa,EACb,EAAE;IACF,MAAM,EAAE,eAAe,EAAE,GAAG,GAAG,CAAC,GAAG,CAAC,MAAM,CAAA;IAE1C,GAAG,CAAC,IAAI,CAAC,MAAM,gBAAgB,CAAC,eAAe,EAAE,GAAG,CAAC,CAAC,CAAA;AACxD,CAAC,CAAA;AAPY,QAAA,aAAa,iBAOzB"}
+2
View File
@@ -0,0 +1,2 @@
import { RequestHandler } from 'express-serve-static-core';
export declare const retryAll: RequestHandler;
+21
View File
@@ -0,0 +1,21 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.retryAll = void 0;
const retryAll = async (req, res) => {
const { queueName } = req.params;
const { bullBoardQueues } = req.app.locals;
const { queue } = bullBoardQueues[queueName];
if (!queue) {
return res.status(404).send({ error: 'queue not found' });
}
else if (queue.readOnlyMode) {
return res.status(405).send({
error: 'Method not allowed on read only queue',
});
}
const jobs = await queue.getJobs(['failed']);
await Promise.all(jobs.map((job) => job.retry()));
return res.sendStatus(200);
};
exports.retryAll = retryAll;
//# sourceMappingURL=retryAll.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"retryAll.js","sourceRoot":"","sources":["../../src/routes/retryAll.ts"],"names":[],"mappings":";;;AAIO,MAAM,QAAQ,GAAmB,KAAK,EAAE,GAAY,EAAE,GAAa,EAAE,EAAE;IAC5E,MAAM,EAAE,SAAS,EAAE,GAAG,GAAG,CAAC,MAAM,CAAA;IAChC,MAAM,EAAE,eAAe,EAAE,GAAG,GAAG,CAAC,GAAG,CAAC,MAEnC,CAAA;IAED,MAAM,EAAE,KAAK,EAAE,GAAG,eAAe,CAAC,SAAS,CAAC,CAAA;IAC5C,IAAI,CAAC,KAAK,EAAE;QACV,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,iBAAiB,EAAE,CAAC,CAAA;KAC1D;SAAM,IAAI,KAAK,CAAC,YAAY,EAAE;QAC7B,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;YAC1B,KAAK,EAAE,uCAAuC;SAC/C,CAAC,CAAA;KACH;IAED,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAA;IAC5C,MAAM,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,CAAA;IAEjD,OAAO,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAA;AAC5B,CAAC,CAAA;AAnBY,QAAA,QAAQ,YAmBpB"}
+2
View File
@@ -0,0 +1,2 @@
import { RequestHandler } from 'express-serve-static-core';
export declare const retryJob: RequestHandler;
+28
View File
@@ -0,0 +1,28 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.retryJob = void 0;
const retryJob = async (req, res) => {
const { bullBoardQueues } = req.app.locals;
const { queueName, id } = req.params;
const { queue } = bullBoardQueues[queueName];
if (!queue) {
return res.status(404).send({
error: 'Queue not found',
});
}
else if (queue.readOnlyMode) {
return res.status(405).send({
error: 'Method not allowed on read only queue',
});
}
const job = await queue.getJob(id);
if (!job) {
return res.status(404).send({
error: 'Job not found',
});
}
await job.retry();
return res.sendStatus(204);
};
exports.retryJob = retryJob;
//# sourceMappingURL=retryJob.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"retryJob.js","sourceRoot":"","sources":["../../src/routes/retryJob.ts"],"names":[],"mappings":";;;AAGO,MAAM,QAAQ,GAAmB,KAAK,EAAE,GAAY,EAAE,GAAa,EAAE,EAAE;IAC5E,MAAM,EAAE,eAAe,EAAE,GAAG,GAAG,CAAC,GAAG,CAAC,MAEnC,CAAA;IACD,MAAM,EAAE,SAAS,EAAE,EAAE,EAAE,GAAG,GAAG,CAAC,MAAM,CAAA;IACpC,MAAM,EAAE,KAAK,EAAE,GAAG,eAAe,CAAC,SAAS,CAAC,CAAA;IAE5C,IAAI,CAAC,KAAK,EAAE;QACV,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;YAC1B,KAAK,EAAE,iBAAiB;SACzB,CAAC,CAAA;KACH;SAAM,IAAI,KAAK,CAAC,YAAY,EAAE;QAC7B,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;YAC1B,KAAK,EAAE,uCAAuC;SAC/C,CAAC,CAAA;KACH;IAED,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;IAElC,IAAI,CAAC,GAAG,EAAE;QACR,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;YAC1B,KAAK,EAAE,eAAe;SACvB,CAAC,CAAA;KACH;IAED,MAAM,GAAG,CAAC,KAAK,EAAE,CAAA;IAEjB,OAAO,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAA;AAC5B,CAAC,CAAA;AA5BY,QAAA,QAAQ,YA4BpB"}