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
+106
View File
@@ -0,0 +1,106 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = formatDistance;
var _index = _interopRequireDefault(require("../localize/index.js"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
// Source: https://www.unicode.org/cldr/charts/32/summary/hi.html
var formatDistanceLocale = {
lessThanXSeconds: {
one: '१ सेकंड से कम',
// CLDR #1310
other: '{{count}} सेकंड से कम'
},
xSeconds: {
one: '१ सेकंड',
other: '{{count}} सेकंड'
},
halfAMinute: 'आधा मिनट',
lessThanXMinutes: {
one: '१ मिनट से कम',
other: '{{count}} मिनट से कम'
},
xMinutes: {
one: '१ मिनट',
// CLDR #1307
other: '{{count}} मिनट'
},
aboutXHours: {
one: 'लगभग १ घंटा',
other: 'लगभग {{count}} घंटे'
},
xHours: {
one: '१ घंटा',
// CLDR #1304
other: '{{count}} घंटे' // CLDR #4467
},
xDays: {
one: '१ दिन',
// CLDR #1286
other: '{{count}} दिन'
},
aboutXWeeks: {
one: 'लगभग १ सप्ताह',
other: 'लगभग {{count}} सप्ताह'
},
xWeeks: {
one: '१ सप्ताह',
other: '{{count}} सप्ताह'
},
aboutXMonths: {
one: 'लगभग १ महीना',
other: 'लगभग {{count}} महीने'
},
xMonths: {
one: '१ महीना',
other: '{{count}} महीने'
},
aboutXYears: {
one: 'लगभग १ वर्ष',
other: 'लगभग {{count}} वर्ष' // CLDR #4823
},
xYears: {
one: '१ वर्ष',
other: '{{count}} वर्ष'
},
overXYears: {
one: '१ वर्ष से अधिक',
other: '{{count}} वर्ष से अधिक'
},
almostXYears: {
one: 'लगभग १ वर्ष',
other: 'लगभग {{count}} वर्ष'
}
};
function formatDistance(token, count, options) {
options = options || {};
var result;
if (typeof formatDistanceLocale[token] === 'string') {
result = formatDistanceLocale[token];
} else if (count === 1) {
result = formatDistanceLocale[token].one;
} else {
result = formatDistanceLocale[token].other.replace('{{count}}', _index.default.numberToLocale(count));
}
if (options.addSuffix) {
if (options.comparison > 0) {
return result + 'मे ';
} else {
return result + ' पहले';
}
}
return result;
}
module.exports = exports.default;
+58
View File
@@ -0,0 +1,58 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _index = _interopRequireDefault(require("../../../_lib/buildFormatLongFn/index.js"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var dateFormats = {
full: 'EEEE, do MMMM, y',
// CLDR #1787
long: 'do MMMM, y',
// CLDR #1788
medium: 'd MMM, y',
// CLDR #1789
short: 'dd/MM/yyyy' // CLDR #1790
};
var timeFormats = {
full: 'h:mm:ss a zzzz',
// CLDR #1791
long: 'h:mm:ss a z',
// CLDR #1792
medium: 'h:mm:ss a',
// CLDR #1793
short: 'h:mm a' // CLDR #1794
};
var dateTimeFormats = {
full: "{{date}} 'को' {{time}}",
// CLDR #1795
long: "{{date}} 'को' {{time}}",
// CLDR #1796
medium: '{{date}}, {{time}}',
// CLDR #1797
short: '{{date}}, {{time}}' // CLDR #1798
};
var formatLong = {
date: (0, _index.default)({
formats: dateFormats,
defaultWidth: 'full'
}),
time: (0, _index.default)({
formats: timeFormats,
defaultWidth: 'full'
}),
dateTime: (0, _index.default)({
formats: dateTimeFormats,
defaultWidth: 'full'
})
};
var _default = formatLong;
exports.default = _default;
module.exports = exports.default;
+20
View File
@@ -0,0 +1,20 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = formatRelative;
var formatRelativeLocale = {
lastWeek: "'पिछले' eeee p",
yesterday: "'कल' p",
today: "'आज' p",
tomorrow: "'कल' p",
nextWeek: "eeee 'को' p",
other: 'P'
};
function formatRelative(token, _date, _baseDate, _options) {
return formatRelativeLocale[token];
}
module.exports = exports.default;
+198
View File
@@ -0,0 +1,198 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _index = _interopRequireDefault(require("../../../_lib/buildLocalizeFn/index.js"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var numberValues = {
locale: {
'1': '१',
'2': '२',
'3': '३',
'4': '४',
'5': '५',
'6': '६',
'7': '७',
'8': '८',
'9': '९',
'0': ''
},
number: {
'१': '1',
'२': '2',
'३': '3',
'४': '4',
'५': '5',
'६': '6',
'७': '7',
'८': '8',
'९': '9',
'': '0'
} // CLDR #1585 - #1592
};
var eraValues = {
narrow: ['ईसा-पूर्व', 'ईस्वी'],
abbreviated: ['ईसा-पूर्व', 'ईस्वी'],
wide: ['ईसा-पूर्व', 'ईसवी सन'] // CLDR #1593 - #1616
};
var quarterValues = {
narrow: ['1', '2', '3', '4'],
abbreviated: ['ति1', 'ति2', 'ति3', 'ति4'],
wide: ['पहली तिमाही', 'दूसरी तिमाही', 'तीसरी तिमाही', 'चौथी तिमाही'] // Note: in English, the names of days of the week and months are capitalized.
// If you are making a new locale based on this one, check if the same is true for the language you're working on.
// Generally, formatted dates should look like they are in the middle of a sentence,
// e.g. in Spanish language the weekdays and months should be in the lowercase.
// https://www.unicode.org/cldr/charts/32/summary/hi.html
// CLDR #1617 - #1688
};
var monthValues = {
narrow: ['ज', 'फ़', 'मा', 'अ', 'मई', 'जू', 'जु', 'अग', 'सि', 'अक्तू', 'न', 'दि'],
abbreviated: ['जन', 'फ़र', 'मार्च', 'अप्रैल', 'मई', 'जून', 'जुल', 'अग', 'सित', 'अक्तू', 'नव', 'दिस'],
wide: ['जनवरी', 'फ़रवरी', 'मार्च', 'अप्रैल', 'मई', 'जून', 'जुलाई', 'अगस्त', 'सितंबर', 'अक्तूबर', 'नवंबर', 'दिसंबर'] // CLDR #1689 - #1744
};
var dayValues = {
narrow: ['र', 'सो', 'मं', 'बु', 'गु', 'शु', 'श'],
short: ['र', 'सो', 'मं', 'बु', 'गु', 'शु', 'श'],
abbreviated: ['रवि', 'सोम', 'मंगल', 'बुध', 'गुरु', 'शुक्र', 'शनि'],
wide: ['रविवार', 'सोमवार', 'मंगलवार', 'बुधवार', 'गुरुवार', 'शुक्रवार', 'शनिवार']
};
var dayPeriodValues = {
narrow: {
am: 'पूर्वाह्न',
pm: 'अपराह्न',
midnight: 'मध्यरात्रि',
noon: 'दोपहर',
morning: 'सुबह',
afternoon: 'दोपहर',
evening: 'शाम',
night: 'रात'
},
abbreviated: {
am: 'पूर्वाह्न',
pm: 'अपराह्न',
midnight: 'मध्यरात्रि',
noon: 'दोपहर',
morning: 'सुबह',
afternoon: 'दोपहर',
evening: 'शाम',
night: 'रात'
},
wide: {
am: 'पूर्वाह्न',
pm: 'अपराह्न',
midnight: 'मध्यरात्रि',
noon: 'दोपहर',
morning: 'सुबह',
afternoon: 'दोपहर',
evening: 'शाम',
night: 'रात'
}
};
var formattingDayPeriodValues = {
narrow: {
am: 'पूर्वाह्न',
pm: 'अपराह्न',
midnight: 'मध्यरात्रि',
noon: 'दोपहर',
morning: 'सुबह',
afternoon: 'दोपहर',
evening: 'शाम',
night: 'रात'
},
abbreviated: {
am: 'पूर्वाह्न',
pm: 'अपराह्न',
midnight: 'मध्यरात्रि',
noon: 'दोपहर',
morning: 'सुबह',
afternoon: 'दोपहर',
evening: 'शाम',
night: 'रात'
},
wide: {
am: 'पूर्वाह्न',
pm: 'अपराह्न',
midnight: 'मध्यरात्रि',
noon: 'दोपहर',
morning: 'सुबह',
afternoon: 'दोपहर',
evening: 'शाम',
night: 'रात'
}
};
function ordinalNumber(dirtyNumber) {
var number = localize.localeToNumber(dirtyNumber);
var localeNumber = localize.numberToLocale(number);
var rem10 = number % 10;
switch (rem10) {
case 2:
case 3:
case 4:
case 6:
case 1:
case 5:
case 7:
case 8:
case 9:
case 0:
return localeNumber;
}
}
function localeToNumber(locale) {
var number = locale.toString().replace(/[१२३४५६७८९०]/g, function (match) {
return numberValues.number[match];
});
return Number(number);
}
function numberToLocale(number) {
return number.toString().replace(/\d/g, function (match) {
return numberValues.locale[match];
});
}
var localize = {
localeToNumber: localeToNumber,
numberToLocale: numberToLocale,
ordinalNumber: ordinalNumber,
era: (0, _index.default)({
values: eraValues,
defaultWidth: 'wide'
}),
quarter: (0, _index.default)({
values: quarterValues,
defaultWidth: 'wide',
argumentCallback: function (quarter) {
return Number(quarter) - 1;
}
}),
month: (0, _index.default)({
values: monthValues,
defaultWidth: 'wide'
}),
day: (0, _index.default)({
values: dayValues,
defaultWidth: 'wide'
}),
dayPeriod: (0, _index.default)({
values: dayPeriodValues,
defaultWidth: 'wide',
formattingValues: formattingDayPeriodValues,
defaultFormattingWidth: 'wide'
})
};
var _default = localize;
exports.default = _default;
module.exports = exports.default;
+111
View File
@@ -0,0 +1,111 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _index = _interopRequireDefault(require("../../../_lib/buildMatchPatternFn/index.js"));
var _index2 = _interopRequireDefault(require("../../../_lib/buildMatchFn/index.js"));
var _index3 = _interopRequireDefault(require("../localize/index.js"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var matchOrdinalNumberPattern = /^[०१२३४५६७८९]+/i;
var parseOrdinalNumberPattern = /^[०१२३४५६७८९]+/i;
var matchEraPatterns = {
narrow: /^(ईसा-पूर्व|ईस्वी)/i,
abbreviated: /^(ईसा\.?\s?पूर्व\.?|ईसा\.?)/i,
wide: /^(ईसा-पूर्व|ईसवी पूर्व|ईसवी सन|ईसवी)/i
};
var parseEraPatterns = {
any: [/^b/i, /^(a|c)/i]
};
var matchQuarterPatterns = {
narrow: /^[1234]/i,
abbreviated: /^ति[1234]/i,
wide: /^[1234](पहली|दूसरी|तीसरी|चौथी)? तिमाही/i
};
var parseQuarterPatterns = {
any: [/1/i, /2/i, /3/i, /4/i]
};
var matchMonthPatterns = {
narrow: /^[जफ़माअप्मईजूनजुअगसिअक्तनदि]/i,
abbreviated: /^(जन|फ़र|मार्च|अप्|मई|जून|जुल|अग|सित|अक्तू|नव|दिस)/i,
wide: /^(जनवरी|फ़रवरी|मार्च|अप्रैल|मई|जून|जुलाई|अगस्त|सितंबर|अक्तूबर|नवंबर|दिसंबर)/i
};
var parseMonthPatterns = {
narrow: [/^ज/i, /^फ़/i, /^मा/i, /^अप्/i, /^मई/i, /^जू/i, /^जु/i, /^अग/i, /^सि/i, /^अक्तू/i, /^न/i, /^दि/i],
any: [/^जन/i, /^फ़/i, /^मा/i, /^अप्/i, /^मई/i, /^जू/i, /^जु/i, /^अग/i, /^सि/i, /^अक्तू/i, /^नव/i, /^दिस/i]
};
var matchDayPatterns = {
narrow: /^[रविसोममंगलबुधगुरुशुक्रशनि]/i,
short: /^(रवि|सोम|मंगल|बुध|गुरु|शुक्र|शनि)/i,
abbreviated: /^(रवि|सोम|मंगल|बुध|गुरु|शुक्र|शनि)/i,
wide: /^(रविवार|सोमवार|मंगलवार|बुधवार|गुरुवार|शुक्रवार|शनिवार)/i
};
var parseDayPatterns = {
narrow: [/^रवि/i, /^सोम/i, /^मंगल/i, /^बुध/i, /^गुरु/i, /^शुक्र/i, /^शनि/i],
any: [/^रवि/i, /^सोम/i, /^मंगल/i, /^बुध/i, /^गुरु/i, /^शुक्र/i, /^शनि/i]
};
var matchDayPeriodPatterns = {
narrow: /^(पू|अ|म|द.\?|सु|दो|शा|रा)/i,
any: /^(पूर्वाह्न|अपराह्न|म|द.\?|सु|दो|शा|रा)/i
};
var parseDayPeriodPatterns = {
any: {
am: /^पूर्वाह्न/i,
pm: /^अपराह्न/i,
midnight: /^मध्य/i,
noon: /^दो/i,
morning: /सु/i,
afternoon: /दो/i,
evening: /शा/i,
night: /रा/i
}
};
var match = {
ordinalNumber: (0, _index.default)({
matchPattern: matchOrdinalNumberPattern,
parsePattern: parseOrdinalNumberPattern,
valueCallback: _index3.default.localeToNumber
}),
era: (0, _index2.default)({
matchPatterns: matchEraPatterns,
defaultMatchWidth: 'wide',
parsePatterns: parseEraPatterns,
defaultParseWidth: 'any'
}),
quarter: (0, _index2.default)({
matchPatterns: matchQuarterPatterns,
defaultMatchWidth: 'wide',
parsePatterns: parseQuarterPatterns,
defaultParseWidth: 'any',
valueCallback: function (index) {
return index + 1;
}
}),
month: (0, _index2.default)({
matchPatterns: matchMonthPatterns,
defaultMatchWidth: 'wide',
parsePatterns: parseMonthPatterns,
defaultParseWidth: 'any'
}),
day: (0, _index2.default)({
matchPatterns: matchDayPatterns,
defaultMatchWidth: 'wide',
parsePatterns: parseDayPatterns,
defaultParseWidth: 'any'
}),
dayPeriod: (0, _index2.default)({
matchPatterns: matchDayPeriodPatterns,
defaultMatchWidth: 'any',
parsePatterns: parseDayPeriodPatterns,
defaultParseWidth: 'any'
})
};
var _default = match;
exports.default = _default;
module.exports = exports.default;