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
+94
View File
@@ -0,0 +1,94 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = formatDistance;
var formatDistanceLocale = {
lessThanXSeconds: {
one: 'më pak se një sekondë',
other: 'më pak se {{count}} sekonda'
},
xSeconds: {
one: '1 sekondë',
other: '{{count}} sekonda'
},
halfAMinute: 'gjysëm minuti',
lessThanXMinutes: {
one: 'më pak se një minute',
other: 'më pak se {{count}} minuta'
},
xMinutes: {
one: '1 minutë',
other: '{{count}} minuta'
},
aboutXHours: {
one: 'rreth 1 orë',
other: 'rreth {{count}} orë'
},
xHours: {
one: '1 orë',
other: '{{count}} orë'
},
xDays: {
one: '1 ditë',
other: '{{count}} ditë'
},
aboutXWeeks: {
one: 'rreth 1 javë',
other: 'rreth {{count}} javë'
},
xWeeks: {
one: '1 javë',
other: '{{count}} javë'
},
aboutXMonths: {
one: 'rreth 1 muaj',
other: 'rreth {{count}} muaj'
},
xMonths: {
one: '1 muaj',
other: '{{count}} muaj'
},
aboutXYears: {
one: 'rreth 1 vit',
other: 'rreth {{count}} vite'
},
xYears: {
one: '1 vit',
other: '{{count}} vite'
},
overXYears: {
one: 'mbi 1 vit',
other: 'mbi {{count}} vite'
},
almostXYears: {
one: 'pothuajse 1 vit',
other: 'pothuajse {{count}} vite'
}
};
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}}', count);
}
if (options.addSuffix) {
if (options.comparison > 0) {
return 'në ' + result;
} else {
return result + ' më parë';
}
}
return result;
}
module.exports = exports.default;
+46
View File
@@ -0,0 +1,46 @@
"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, MMMM do, y',
long: 'MMMM do, y',
medium: 'MMM d, y',
short: 'MM/dd/yyyy'
};
var timeFormats = {
full: 'h:mm:ss a zzzz',
long: 'h:mm:ss a z',
medium: 'h:mm:ss a',
short: 'h:mm a'
};
var dateTimeFormats = {
full: "{{date}} 'në' {{time}}",
long: "{{date}} 'në' {{time}}",
medium: '{{date}}, {{time}}',
short: '{{date}}, {{time}}'
};
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: "'të' eeee 'e shkuar në' p",
yesterday: "'dje në' p",
today: "'sot në' p",
tomorrow: "'nesër në' p",
nextWeek: "eeee 'at' p",
other: 'P'
};
function formatRelative(token, _date, _baseDate, _options) {
return formatRelativeLocale[token];
}
module.exports = exports.default;
+151
View File
@@ -0,0 +1,151 @@
"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 eraValues = {
narrow: ['P', 'M'],
abbreviated: ['PK', 'MK'],
wide: ['Para Krishtit', 'Mbas Krishtit']
};
var quarterValues = {
narrow: ['1', '2', '3', '4'],
abbreviated: ['Q1', 'Q2', 'Q3', 'Q4'],
wide: ['4-mujori I', '4-mujori II', '4-mujori III', '4-mujori IV'] // 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.
};
var monthValues = {
narrow: ['J', 'S', 'M', 'P', 'M', 'Q', 'K', 'G', 'S', 'T', 'N', 'D'],
abbreviated: ['Jan', 'Shk', 'Mar', 'Pri', 'Maj', 'Qer', 'Kor', 'Gus', 'Sht', 'Tet', 'Nën', 'Dhj'],
wide: ['Janar', 'Shkurt', 'Mars', 'Prill', 'Maj', 'Qershor', 'Korrik', 'Gusht', 'Shtator', 'Tetor', 'Nëntor', 'Dhjetor']
};
var dayValues = {
narrow: ['D', 'H', 'M', 'M', 'E', 'P', 'S'],
short: ['Di', 'Hë', 'Ma', 'Më', 'En', 'Pr', 'Sh'],
abbreviated: ['Die', 'Hën', 'Mar', 'Mër', 'Enj', 'Pre', 'Sht'],
wide: ['Dielë', 'Hënë', 'Martë', 'Mërkurë', 'Enjte', 'Premte', 'Shtunë']
};
var dayPeriodValues = {
narrow: {
am: 'p',
pm: 'm',
midnight: 'm',
noon: 'd',
morning: 'mëngjes',
afternoon: 'dite',
evening: 'mbrëmje',
night: 'natë'
},
abbreviated: {
am: 'PD',
pm: 'MD',
midnight: 'mesnëtë',
noon: 'drek',
morning: 'mëngjes',
afternoon: 'mbasdite',
evening: 'mbrëmje',
night: 'natë'
},
wide: {
am: 'p.d.',
pm: 'm.d.',
midnight: 'mesnëtë',
noon: 'drek',
morning: 'mëngjes',
afternoon: 'mbasdite',
evening: 'mbrëmje',
night: 'natë'
}
};
var formattingDayPeriodValues = {
narrow: {
am: 'p',
pm: 'm',
midnight: 'm',
noon: 'd',
morning: 'në mëngjes',
afternoon: 'në mbasdite',
evening: 'në mbrëmje',
night: 'në mesnatë'
},
abbreviated: {
am: 'PD',
pm: 'MD',
midnight: 'mesnatë',
noon: 'drek',
morning: 'në mëngjes',
afternoon: 'në mbasdite',
evening: 'në mbrëmje',
night: 'në mesnatë'
},
wide: {
am: 'p.d.',
pm: 'm.d.',
midnight: 'mesnatë',
noon: 'drek',
morning: 'në mëngjes',
afternoon: 'në mbasdite',
evening: 'në mbrëmje',
night: 'në mesnatë'
}
};
function ordinalNumber(dirtyNumber, _dirtyOptions) {
var number = Number(dirtyNumber); // If ordinal numbers depend on context, for example,
// if they are different for different grammatical genders,
// use `options.unit`:
//
// var options = dirtyOptions || {}
// var unit = String(options.unit)
//
// where `unit` can be 'year', 'quarter', 'month', 'week', 'date', 'dayOfYear',
// 'day', 'hour', 'minute', 'second'
var options = _dirtyOptions || {};
var unit = String(options.unit);
if (unit === 'hour') return number;
if (number === 1) return number + '-rë';
if (number === 4) return number + 't';
return number + '-të';
}
var localize = {
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"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var matchOrdinalNumberPattern = /^(\d+)(-rë|-të|t|)?/i;
var parseOrdinalNumberPattern = /\d+/i;
var matchEraPatterns = {
narrow: /^(p|m)/i,
abbreviated: /^(b\.?\s?c\.?|b\.?\s?c\.?\s?e\.?|a\.?\s?d\.?|c\.?\s?e\.?)/i,
wide: /^(para krishtit|mbas krishtit)/i
};
var parseEraPatterns = {
any: [/^b/i, /^(p|m)/i]
};
var matchQuarterPatterns = {
narrow: /^[1234]/i,
abbreviated: /^q[1234]/i,
wide: /^[1234]-mujori (i{1,3}|iv)/i
};
var parseQuarterPatterns = {
any: [/1/i, /2/i, /3/i, /4/i]
};
var matchMonthPatterns = {
narrow: /^[jsmpqkftnd]/i,
abbreviated: /^(jan|shk|mar|pri|maj|qer|kor|gus|sht|tet|nën|dhj)/i,
wide: /^(janar|shkurt|mars|prill|maj|qershor|korrik|gusht|shtator|tetor|nëntor|dhjetor)/i
};
var parseMonthPatterns = {
narrow: [/^j/i, /^s/i, /^m/i, /^p/i, /^m/i, /^q/i, /^k/i, /^g/i, /^s/i, /^t/i, /^n/i, /^d/i],
any: [/^ja/i, /^shk/i, /^mar/i, /^pri/i, /^maj/i, /^qer/i, /^kor/i, /^gu/i, /^sht/i, /^tet/i, /^n/i, /^d/i]
};
var matchDayPatterns = {
narrow: /^[dhmeps]/i,
short: /^(di|hë|ma|më|en|pr|sh)/i,
abbreviated: /^(die|hën|mar|mër|enj|pre|sht)/i,
wide: /^(dielë|hënë|martë|mërkurë|enjte|premte|shtunë)/i
};
var parseDayPatterns = {
narrow: [/^d/i, /^h/i, /^m/i, /^m/i, /^e/i, /^p/i, /^s/i],
any: [/^d/i, /^h/i, /^ma/i, /^më/i, /^e/i, /^p/i, /^s/i]
};
var matchDayPeriodPatterns = {
narrow: /^(p|m|me|në (mëngjes|mbasdite|mbrëmje|mesnatë))/i,
any: /^([pm]\.?\s?d\.?|drek|në (mëngjes|mbasdite|mbrëmje|mesnatë))/i
};
var parseDayPeriodPatterns = {
any: {
am: /^p/i,
pm: /^m/i,
midnight: /^me/i,
noon: /^dr/i,
morning: /mëngjes/i,
afternoon: /mbasdite/i,
evening: /mbrëmje/i,
night: /natë/i
}
};
var match = {
ordinalNumber: (0, _index.default)({
matchPattern: matchOrdinalNumberPattern,
parsePattern: parseOrdinalNumberPattern,
valueCallback: function (value) {
return parseInt(value, 10);
}
}),
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;