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,5 @@
/// <reference types="react" />
import { AppQueue } from '../../../@types/app';
export declare const StatusMenu: ({ queue }: {
queue: AppQueue;
}) => JSX.Element;
@@ -0,0 +1,26 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.StatusMenu = void 0;
const react_1 = __importDefault(require("react"));
const react_router_dom_1 = require("react-router-dom");
const constants_1 = require("../constants");
const StatusMenu_module_css_1 = __importDefault(require("./StatusMenu.module.css"));
const StatusMenu = ({ queue }) => {
const { url } = react_router_dom_1.useRouteMatch();
return (react_1.default.createElement("div", { className: StatusMenu_module_css_1.default.statusMenu }, constants_1.STATUS_LIST.map((status) => {
const isLatest = status === constants_1.STATUSES.latest;
const displayStatus = status.toLocaleUpperCase();
return (react_1.default.createElement(react_router_dom_1.NavLink, { to: `${url}${isLatest ? '' : `?status=${status}`}`, activeClassName: StatusMenu_module_css_1.default.active, isActive: (_path, { search }) => {
const query = new URLSearchParams(search);
return (query.get('status') === status ||
(isLatest && query.get('status') === null));
}, key: `${queue.name}-${status}` },
react_1.default.createElement("span", { title: displayStatus }, displayStatus),
queue.counts[status] > 0 && (react_1.default.createElement("span", { className: StatusMenu_module_css_1.default.badge }, queue.counts[status]))));
})));
};
exports.StatusMenu = StatusMenu;
//# sourceMappingURL=StatusMenu.js.map
@@ -0,0 +1 @@
{"version":3,"file":"StatusMenu.js","sourceRoot":"","sources":["../../../../src/ui/components/StatusMenu/StatusMenu.tsx"],"names":[],"mappings":";;;;;;AAAA,kDAAyB;AACzB,uDAAyD;AAEzD,4CAAoD;AACpD,oFAAuC;AAEhC,MAAM,UAAU,GAAG,CAAC,EAAE,KAAK,EAAuB,EAAE,EAAE;IAC3D,MAAM,EAAE,GAAG,EAAE,GAAG,gCAAa,EAAE,CAAA;IAE/B,OAAO,CACL,uCAAK,SAAS,EAAE,+BAAC,CAAC,UAAU,IACzB,uBAAW,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;QAC1B,MAAM,QAAQ,GAAG,MAAM,KAAK,oBAAQ,CAAC,MAAM,CAAA;QAC3C,MAAM,aAAa,GAAG,MAAM,CAAC,iBAAiB,EAAE,CAAA;QAChD,OAAO,CACL,8BAAC,0BAAO,IACN,EAAE,EAAE,GAAG,GAAG,GAAG,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,MAAM,EAAE,EAAE,EAClD,eAAe,EAAE,+BAAC,CAAC,MAAM,EACzB,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE;gBAC9B,MAAM,KAAK,GAAG,IAAI,eAAe,CAAC,MAAM,CAAC,CAAA;gBACzC,OAAO,CACL,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,MAAM;oBAC9B,CAAC,QAAQ,IAAI,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,IAAI,CAAC,CAC3C,CAAA;YACH,CAAC,EACD,GAAG,EAAE,GAAG,KAAK,CAAC,IAAI,IAAI,MAAM,EAAE;YAE9B,wCAAM,KAAK,EAAE,aAAa,IAAG,aAAa,CAAQ;YACjD,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAC3B,wCAAM,SAAS,EAAE,+BAAC,CAAC,KAAK,IAAG,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAQ,CACxD,CACO,CACX,CAAA;IACH,CAAC,CAAC,CACE,CACP,CAAA;AACH,CAAC,CAAA;AA9BY,QAAA,UAAU,cA8BtB"}