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
@@ -0,0 +1,8 @@
/// <reference types="react" />
import { AppQueue } from '../../../@types/app';
import { Store } from '../../hooks/useStore';
export declare const QueuePage: ({ selectedStatus, actions, queue, }: {
queue: AppQueue | undefined;
actions: Store['actions'];
selectedStatus: Store['selectedStatuses'];
}) => JSX.Element;
@@ -0,0 +1,28 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.QueuePage = void 0;
const react_1 = __importDefault(require("react"));
const JobCard_1 = require("../JobCard/JobCard");
const QueueActions_1 = require("../QueueActions/QueueActions");
const StatusMenu_1 = require("../StatusMenu/StatusMenu");
const QueuePage_module_css_1 = __importDefault(require("./QueuePage.module.css"));
const QueuePage = ({ selectedStatus, actions, queue, }) => {
if (!queue) {
return react_1.default.createElement("section", null, "Queue Not found");
}
return (react_1.default.createElement("section", null,
react_1.default.createElement("div", { className: QueuePage_module_css_1.default.stickyHeader },
react_1.default.createElement(StatusMenu_1.StatusMenu, { queue: queue }),
!queue.readOnlyMode && (react_1.default.createElement(QueueActions_1.QueueActions, { queue: queue, actions: actions, status: selectedStatus[queue.name] }))),
queue.jobs.map((job) => (react_1.default.createElement(JobCard_1.JobCard, { key: job.id, job: job, status: selectedStatus[queue.name], actions: {
cleanJob: actions.cleanJob(queue === null || queue === void 0 ? void 0 : queue.name)(job),
promoteJob: actions.promoteJob(queue === null || queue === void 0 ? void 0 : queue.name)(job),
retryJob: actions.retryJob(queue === null || queue === void 0 ? void 0 : queue.name)(job),
getJobLogs: actions.getJobLogs(queue === null || queue === void 0 ? void 0 : queue.name)(job),
}, readOnlyMode: queue === null || queue === void 0 ? void 0 : queue.readOnlyMode })))));
};
exports.QueuePage = QueuePage;
//# sourceMappingURL=QueuePage.js.map
@@ -0,0 +1 @@
{"version":3,"file":"QueuePage.js","sourceRoot":"","sources":["../../../../src/ui/components/QueuePage/QueuePage.tsx"],"names":[],"mappings":";;;;;;AAAA,kDAAyB;AAGzB,gDAA4C;AAC5C,+DAA2D;AAC3D,yDAAqD;AACrD,kFAAsC;AAE/B,MAAM,SAAS,GAAG,CAAC,EACxB,cAAc,EACd,OAAO,EACP,KAAK,GAKN,EAAE,EAAE;IACH,IAAI,CAAC,KAAK,EAAE;QACV,OAAO,iEAAkC,CAAA;KAC1C;IAED,OAAO,CACL;QACE,uCAAK,SAAS,EAAE,8BAAC,CAAC,YAAY;YAC5B,8BAAC,uBAAU,IAAC,KAAK,EAAE,KAAK,GAAI;YAC3B,CAAC,KAAK,CAAC,YAAY,IAAI,CACtB,8BAAC,2BAAY,IACX,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,cAAc,CAAC,KAAK,CAAC,IAAI,CAAC,GAClC,CACH,CACG;QACL,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CACvB,8BAAC,iBAAO,IACN,GAAG,EAAE,GAAG,CAAC,EAAE,EACX,GAAG,EAAE,GAAG,EACR,MAAM,EAAE,cAAc,CAAC,KAAK,CAAC,IAAI,CAAC,EAClC,OAAO,EAAE;gBACP,QAAQ,EAAE,OAAO,CAAC,QAAQ,CAAC,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,IAAI,CAAC,CAAC,GAAG,CAAC;gBAC5C,UAAU,EAAE,OAAO,CAAC,UAAU,CAAC,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,IAAI,CAAC,CAAC,GAAG,CAAC;gBAChD,QAAQ,EAAE,OAAO,CAAC,QAAQ,CAAC,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,IAAI,CAAC,CAAC,GAAG,CAAC;gBAC5C,UAAU,EAAE,OAAO,CAAC,UAAU,CAAC,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,IAAI,CAAC,CAAC,GAAG,CAAC;aACjD,EACD,YAAY,EAAE,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,YAAY,GACjC,CACH,CAAC,CACM,CACX,CAAA;AACH,CAAC,CAAA;AAzCY,QAAA,SAAS,aAyCrB"}