@vilio/auth-passkey-module 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/dist/actions/settings.d.ts +10 -0
  2. package/dist/actions/settings.d.ts.map +1 -0
  3. package/dist/actions/settings.js +17 -0
  4. package/dist/actions/settings.js.map +1 -0
  5. package/dist/client.d.ts +1 -0
  6. package/dist/client.d.ts.map +1 -0
  7. package/dist/client.js +3 -0
  8. package/dist/client.js.map +1 -0
  9. package/dist/index.d.ts +4 -0
  10. package/dist/index.d.ts.map +1 -0
  11. package/dist/index.js +118 -0
  12. package/dist/index.js.map +1 -0
  13. package/dist/routes.d.ts +5 -0
  14. package/dist/routes.d.ts.map +1 -0
  15. package/dist/routes.js +195 -0
  16. package/dist/routes.js.map +1 -0
  17. package/dist/schema.d.ts +415 -0
  18. package/dist/schema.d.ts.map +1 -0
  19. package/dist/schema.js +28 -0
  20. package/dist/schema.js.map +1 -0
  21. package/dist/server/passkey.d.ts +8 -0
  22. package/dist/server/passkey.d.ts.map +1 -0
  23. package/dist/server/passkey.js +126 -0
  24. package/dist/server/passkey.js.map +1 -0
  25. package/dist/ui/passkey-button.d.ts +2 -0
  26. package/dist/ui/passkey-button.d.ts.map +1 -0
  27. package/dist/ui/passkey-button.js +56 -0
  28. package/dist/ui/passkey-button.js.map +1 -0
  29. package/dist/ui/session-badge.d.ts +5 -0
  30. package/dist/ui/session-badge.d.ts.map +1 -0
  31. package/dist/ui/session-badge.js +16 -0
  32. package/dist/ui/session-badge.js.map +1 -0
  33. package/dist/ui/settings-auth-passkey.d.ts +2 -0
  34. package/dist/ui/settings-auth-passkey.d.ts.map +1 -0
  35. package/dist/ui/settings-auth-passkey.js +32 -0
  36. package/dist/ui/settings-auth-passkey.js.map +1 -0
  37. package/dist/ui/settings-passkey.d.ts +2 -0
  38. package/dist/ui/settings-passkey.d.ts.map +1 -0
  39. package/dist/ui/settings-passkey.js +110 -0
  40. package/dist/ui/settings-passkey.js.map +1 -0
  41. package/dist/ui/verify-page.d.ts +2 -0
  42. package/dist/ui/verify-page.d.ts.map +1 -0
  43. package/dist/ui/verify-page.js +45 -0
  44. package/dist/ui/verify-page.js.map +1 -0
  45. package/locales/en/global.json +52 -0
  46. package/locales/pl/global.json +52 -0
  47. package/manifest.json +11 -0
  48. package/package.json +45 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-badge.d.ts","sourceRoot":"","sources":["../../src/ui/session-badge.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAEtC,wBAAgB,uBAAuB,CAAC,EAAE,OAAO,EAAE,EAAE;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE,kDAuBxE"}
@@ -0,0 +1,16 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useTranslation } from "@vilio/intl";
4
+ import { Badge, Icon, cn } from "@vilio/ui";
5
+ export function Passkey2FAVerifiedBadge({ session }) {
6
+ const { t } = useTranslation();
7
+ // Use the verified flag from the session object
8
+ const isVerified = session["2faVerified"] === true ||
9
+ session.passkey_verified === true ||
10
+ // @ts-ignore
11
+ session.metadata?.passkey_verified === true;
12
+ if (!isVerified)
13
+ return null;
14
+ return (_jsxs(Badge, { variant: "outline", className: cn("text-[10px] px-1.5 text-green-600 border-green-200 bg-green-50"), children: [_jsx(Icon, { icon: "solar:shield-check-broken", className: "h-2.5 w-2.5 mr-0.5" }), t("2FA Verified")] }));
15
+ }
16
+ //# sourceMappingURL=session-badge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-badge.js","sourceRoot":"","sources":["../../src/ui/session-badge.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AACb,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,WAAW,CAAC;AAI5C,MAAM,UAAU,uBAAuB,CAAC,EAAE,OAAO,EAAwB;IACvE,MAAM,EAAE,CAAC,EAAE,GAAG,cAAc,EAAE,CAAC;IAE/B,gDAAgD;IAChD,MAAM,UAAU,GACd,OAAO,CAAC,aAAa,CAAC,KAAK,IAAI;QAC/B,OAAO,CAAC,gBAAgB,KAAK,IAAI;QACjC,aAAa;QACb,OAAO,CAAC,QAAQ,EAAE,gBAAgB,KAAK,IAAI,CAAC;IAE9C,IAAI,CAAC,UAAU;QAAE,OAAO,IAAI,CAAC;IAE7B,OAAO,CACL,MAAC,KAAK,IACJ,OAAO,EAAC,SAAS,EACjB,SAAS,EAAE,EAAE,CACX,gEAAgE,CACjE,aAED,KAAC,IAAI,IAAC,IAAI,EAAC,2BAA2B,EAAC,SAAS,EAAC,oBAAoB,GAAG,EACvE,CAAC,CAAC,cAAc,CAAC,IACZ,CACT,CAAC;AACJ,CAAC"}
@@ -0,0 +1,2 @@
1
+ export default function PasskeySettingsPage(): import("react/jsx-runtime").JSX.Element;
2
+ //# sourceMappingURL=settings-auth-passkey.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settings-auth-passkey.d.ts","sourceRoot":"","sources":["../../src/ui/settings-auth-passkey.tsx"],"names":[],"mappings":"AAqBA,MAAM,CAAC,OAAO,UAAU,mBAAmB,4CAmF1C"}
@@ -0,0 +1,32 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useTransition, useEffect, useState } from "react";
4
+ import { toast } from "sonner";
5
+ import { Card, CardHeader, CardTitle, CardDescription, CardContent, Button, Input, Label, } from "@vilio/ui";
6
+ import { getPasskeyConfig, updatePasskeyConfig, } from "../actions/settings";
7
+ import { useTranslation } from "@vilio/intl";
8
+ export default function PasskeySettingsPage() {
9
+ const { t } = useTranslation();
10
+ const [config, setConfig] = useState({
11
+ rpName: "",
12
+ rpId: "",
13
+ origin: "",
14
+ });
15
+ const [isPending, startTransition] = useTransition();
16
+ useEffect(() => {
17
+ getPasskeyConfig().then(setConfig);
18
+ }, []);
19
+ const handleSave = () => {
20
+ startTransition(async () => {
21
+ const result = await updatePasskeyConfig(config);
22
+ if (result.success) {
23
+ toast.success(t("Settings saved successfully"));
24
+ }
25
+ else {
26
+ toast.error(t("Failed to save settings"));
27
+ }
28
+ });
29
+ };
30
+ return (_jsx("div", { className: "container max-w-2xl py-8", children: _jsxs(Card, { children: [_jsxs(CardHeader, { children: [_jsx(CardTitle, { children: t("Passkey Configuration") }), _jsx(CardDescription, { children: t("Configure Relying Party settings for WebAuthn.") })] }), _jsxs(CardContent, { className: "space-y-4", children: [_jsxs("div", { className: "space-y-2", children: [_jsx(Label, { htmlFor: "rpName", children: t("RP Name") }), _jsx(Input, { id: "rpName", value: config.rpName, onChange: (e) => setConfig({ ...config, rpName: e.target.value }), placeholder: "Vilio Turbo" }), _jsx("p", { className: "text-sm text-muted-foreground", children: t("A user-friendly name of the service.") })] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { htmlFor: "rpId", children: t("RP ID") }), _jsx(Input, { id: "rpId", value: config.rpId, onChange: (e) => setConfig({ ...config, rpId: e.target.value }), placeholder: "localhost" }), _jsx("p", { className: "text-sm text-muted-foreground", children: t("The domain name where the service is hosted.") })] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { htmlFor: "origin", children: t("Origin") }), _jsx(Input, { id: "origin", value: config.origin, onChange: (e) => setConfig({ ...config, origin: e.target.value }), placeholder: "http://localhost:3000" }), _jsx("p", { className: "text-sm text-muted-foreground", children: t("The full origin of the service, including protocol and port.") })] }), _jsx(Button, { onClick: handleSave, disabled: isPending, children: isPending ? t("Saving...") : t("Save Settings") })] })] }) }));
31
+ }
32
+ //# sourceMappingURL=settings-auth-passkey.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settings-auth-passkey.js","sourceRoot":"","sources":["../../src/ui/settings-auth-passkey.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function PasskeySettings(): import("react/jsx-runtime").JSX.Element;
2
+ //# sourceMappingURL=settings-passkey.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settings-passkey.d.ts","sourceRoot":"","sources":["../../src/ui/settings-passkey.tsx"],"names":[],"mappings":"AAwBA,wBAAgB,eAAe,4CA6N9B"}
@@ -0,0 +1,110 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useTranslation } from "@vilio/intl";
4
+ import { Button, Card, CardContent, CardDescription, CardHeader, CardTitle, Input, Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, Switch, Label, } from "@vilio/ui";
5
+ import { Fingerprint, Plus, Trash2, Edit2, ShieldCheck } from "lucide-react";
6
+ import * as React from "react";
7
+ import { startRegistration } from "@simplewebauthn/browser";
8
+ import { toast } from "sonner";
9
+ export function PasskeySettings() {
10
+ const { t } = useTranslation();
11
+ const [passkeys, setPasskeys] = React.useState([]);
12
+ const [settings, setSettings] = React.useState({ twoFactorEnabled: false });
13
+ const [isEditOpen, setIsEditOpen] = React.useState(false);
14
+ const [editingKey, setEditingKey] = React.useState(null);
15
+ const fetchPasskeys = async () => {
16
+ const resp = await fetch("/api/auth/passkey/list");
17
+ if (resp.ok) {
18
+ setPasskeys(await resp.json());
19
+ }
20
+ };
21
+ const fetchSettings = async () => {
22
+ const resp = await fetch("/api/auth/passkey/settings");
23
+ if (resp.ok) {
24
+ setSettings(await resp.json());
25
+ }
26
+ };
27
+ React.useEffect(() => {
28
+ fetchPasskeys();
29
+ fetchSettings();
30
+ }, []);
31
+ const handleRegister = async () => {
32
+ try {
33
+ const resp = await fetch("/api/auth/passkey/register-options");
34
+ if (!resp.ok)
35
+ throw new Error(t("Failed to get options"));
36
+ const opts = await resp.json();
37
+ const attResp = await startRegistration(opts);
38
+ const verifyResp = await fetch("/api/auth/passkey/register-verify", {
39
+ method: "POST",
40
+ headers: { "Content-Type": "application/json" },
41
+ body: JSON.stringify(attResp),
42
+ });
43
+ if (!verifyResp.ok)
44
+ throw new Error("Verification failed");
45
+ toast.success(t("Passkey registered successfully!"));
46
+ fetchPasskeys();
47
+ }
48
+ catch (err) {
49
+ toast.error(err.message || t("Registration failed."));
50
+ }
51
+ };
52
+ const handleToggle2FA = async (enabled) => {
53
+ try {
54
+ const resp = await fetch("/api/auth/passkey/settings/update", {
55
+ method: "POST",
56
+ headers: { "Content-Type": "application/json" },
57
+ body: JSON.stringify({ enabled }),
58
+ });
59
+ if (resp.ok) {
60
+ setSettings({ ...settings, twoFactorEnabled: enabled });
61
+ toast.success(enabled ? t("Passkey 2FA enabled.") : t("Passkey 2FA disabled."));
62
+ }
63
+ }
64
+ catch (err) {
65
+ toast.error(t("Failed to update settings."));
66
+ }
67
+ };
68
+ const handleDelete = async (id) => {
69
+ if (!confirm(t("Are you sure you want to delete this passkey?")))
70
+ return;
71
+ try {
72
+ const resp = await fetch("/api/auth/passkey/delete", {
73
+ method: "POST",
74
+ headers: { "Content-Type": "application/json" },
75
+ body: JSON.stringify({ id }),
76
+ });
77
+ if (resp.ok) {
78
+ toast.success(t("Passkey deleted."));
79
+ fetchPasskeys();
80
+ }
81
+ }
82
+ catch (err) {
83
+ toast.error(t("Failed to delete."));
84
+ }
85
+ };
86
+ const handleRename = async () => {
87
+ if (!editingKey)
88
+ return;
89
+ try {
90
+ const resp = await fetch("/api/auth/passkey/rename", {
91
+ method: "POST",
92
+ headers: { "Content-Type": "application/json" },
93
+ body: JSON.stringify(editingKey),
94
+ });
95
+ if (resp.ok) {
96
+ toast.success(t("Passkey renamed."));
97
+ setIsEditOpen(false);
98
+ fetchPasskeys();
99
+ }
100
+ }
101
+ catch (err) {
102
+ toast.error(t("Failed to rename."));
103
+ }
104
+ };
105
+ return (_jsxs("div", { className: "space-y-6", children: [_jsxs(Card, { children: [_jsxs(CardHeader, { children: [_jsxs(CardTitle, { className: "flex items-center gap-2", children: [_jsx(ShieldCheck, { className: "size-5" }), t("Passkey Login Verification")] }), _jsx(CardDescription, { children: t("Require passkey verification after traditional login.") })] }), _jsxs(CardContent, { children: [_jsxs("div", { className: "flex items-center space-x-2", children: [_jsx(Switch, { id: "passkey-2fa", checked: settings.twoFactorEnabled, onCheckedChange: handleToggle2FA, disabled: passkeys.length === 0 }), _jsx(Label, { htmlFor: "passkey-2fa", children: t("Enable Passkey 2FA") })] }), passkeys.length === 0 && (_jsx("p", { className: "text-xs text-muted-foreground mt-2", children: t("You must register at least one passkey to enable this feature.") }))] })] }), _jsxs(Card, { children: [_jsxs(CardHeader, { children: [_jsxs(CardTitle, { className: "flex items-center gap-2", children: [_jsx(Fingerprint, { className: "size-5" }), t("Passkeys")] }), _jsx(CardDescription, { children: t("Use biometric authentication to sign in securely.") })] }), _jsxs(CardContent, { className: "space-y-4", children: [passkeys.length > 0 && (_jsx("div", { className: "divide-y border rounded-md", children: passkeys.map((pk) => (_jsxs("div", { className: "p-3 flex items-center justify-between", children: [_jsxs("div", { className: "flex flex-col", children: [_jsx("span", { className: "font-medium", children: pk.name || t("Unnamed Passkey") }), _jsxs("span", { className: "text-xs text-muted-foreground", children: [new Date(pk.createdAt).toLocaleDateString(), " \u2022", " ", pk.deviceType] })] }), _jsxs("div", { className: "flex gap-2", children: [_jsx(Button, { size: "icon", variant: "ghost", onClick: () => {
106
+ setEditingKey({ id: pk.id, name: pk.name || "" });
107
+ setIsEditOpen(true);
108
+ }, children: _jsx(Edit2, { className: "size-4" }) }), _jsx(Button, { size: "icon", variant: "ghost", className: "text-destructive", onClick: () => handleDelete(pk.id), children: _jsx(Trash2, { className: "size-4" }) })] })] }, pk.id))) })), _jsxs(Button, { onClick: handleRegister, className: "gap-2", variant: "outline", children: [_jsx(Plus, { className: "size-4" }), t("Add new Passkey")] }), _jsx(Dialog, { open: isEditOpen, onOpenChange: setIsEditOpen, children: _jsxs(DialogContent, { children: [_jsxs(DialogHeader, { children: [_jsx(DialogTitle, { children: t("Rename Passkey") }), _jsx(DialogDescription, { children: t("Give this passkey a recognizable name.") })] }), _jsx(Input, { value: editingKey?.name || "", onChange: (e) => setEditingKey((prev) => prev ? { ...prev, name: e.target.value } : null), placeholder: t("e.g. My Phone") }), _jsxs(DialogFooter, { children: [_jsx(Button, { variant: "outline", onClick: () => setIsEditOpen(false), children: t("Cancel") }), _jsx(Button, { onClick: handleRename, children: t("Save") })] })] }) })] })] })] }));
109
+ }
110
+ //# sourceMappingURL=settings-passkey.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settings-passkey.js","sourceRoot":"","sources":["../../src/ui/settings-passkey.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export default function PasskeyVerifyPage(): import("react/jsx-runtime").JSX.Element;
2
+ //# sourceMappingURL=verify-page.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify-page.d.ts","sourceRoot":"","sources":["../../src/ui/verify-page.tsx"],"names":[],"mappings":"AAeA,MAAM,CAAC,OAAO,UAAU,iBAAiB,4CA8DxC"}
@@ -0,0 +1,45 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useTranslation } from "@vilio/intl";
4
+ import { Button, Card, CardContent, CardDescription, CardHeader, CardTitle, } from "@vilio/ui";
5
+ import { Fingerprint } from "lucide-react";
6
+ import { startAuthentication } from "@simplewebauthn/browser";
7
+ import { toast } from "sonner";
8
+ export default function PasskeyVerifyPage() {
9
+ const { t } = useTranslation();
10
+ const handleVerify = async () => {
11
+ try {
12
+ // 1. Get options from server
13
+ const resp = await fetch("/api/auth/passkey/login-options");
14
+ if (!resp.ok)
15
+ throw new Error(t("Failed to get login options"));
16
+ const opts = await resp.json();
17
+ // 2. Start authentication
18
+ const asseResp = await startAuthentication(opts);
19
+ // 3. Verify response on server for 2FA
20
+ const verifyResp = await fetch("/api/auth/passkey/2fa-verify", {
21
+ method: "POST",
22
+ headers: { "Content-Type": "application/json" },
23
+ body: JSON.stringify(asseResp),
24
+ });
25
+ if (!verifyResp.ok) {
26
+ const err = await verifyResp.json();
27
+ throw new Error(err.message || t("Verification failed"));
28
+ }
29
+ const result = await verifyResp.json();
30
+ if (result.success) {
31
+ toast.success(t("Identity verified!"));
32
+ window.location.href = "/";
33
+ }
34
+ else {
35
+ toast.error(t("Verification failed."));
36
+ }
37
+ }
38
+ catch (err) {
39
+ console.error(err);
40
+ toast.error(err.message || t("Verification failed."));
41
+ }
42
+ };
43
+ return (_jsx("div", { className: "flex min-h-[50vh] items-center justify-center p-4", children: _jsxs(Card, { className: "w-full max-w-md", children: [_jsxs(CardHeader, { className: "text-center", children: [_jsx("div", { className: "mx-auto mb-4 flex h-12 w-12 items-center justify-center rounded-full bg-primary/10", children: _jsx(Fingerprint, { className: "h-6 w-6 text-primary" }) }), _jsx(CardTitle, { children: t("Passkey Verification") }), _jsx(CardDescription, { children: t("To continue, please verify your identity using one of your registered passkeys.") })] }), _jsx(CardContent, { children: _jsxs(Button, { onClick: handleVerify, className: "w-full gap-2", children: [_jsx(Fingerprint, { className: "size-4" }), t("Authenticate with Passkey")] }) })] }) }));
44
+ }
45
+ //# sourceMappingURL=verify-page.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify-page.js","sourceRoot":"","sources":["../../src/ui/verify-page.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AACb,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EACL,MAAM,EACN,IAAI,EACJ,WAAW,EACX,eAAe,EACf,UAAU,EACV,SAAS,GACV,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE3C,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAE/B,MAAM,CAAC,OAAO,UAAU,iBAAiB;IACvC,MAAM,EAAE,CAAC,EAAE,GAAG,cAAc,EAAE,CAAC;IAE/B,MAAM,YAAY,GAAG,KAAK,IAAI,EAAE;QAC9B,IAAI,CAAC;YACH,6BAA6B;YAC7B,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,iCAAiC,CAAC,CAAC;YAC5D,IAAI,CAAC,IAAI,CAAC,EAAE;gBAAE,MAAM,IAAI,KAAK,CAAC,CAAC,CAAC,6BAA6B,CAAC,CAAC,CAAC;YAChE,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;YAE/B,0BAA0B;YAC1B,MAAM,QAAQ,GAAG,MAAM,mBAAmB,CAAC,IAAI,CAAC,CAAC;YAEjD,uCAAuC;YACvC,MAAM,UAAU,GAAG,MAAM,KAAK,CAAC,8BAA8B,EAAE;gBAC7D,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;gBAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC;aAC/B,CAAC,CAAC;YAEH,IAAI,CAAC,UAAU,CAAC,EAAE,EAAE,CAAC;gBACnB,MAAM,GAAG,GAAG,MAAM,UAAU,CAAC,IAAI,EAAE,CAAC;gBACpC,MAAM,IAAI,KAAK,CAAC,GAAG,CAAC,OAAO,IAAI,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC;YAC3D,CAAC;YAED,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,IAAI,EAAE,CAAC;YAEvC,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;gBACnB,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC;gBACvC,MAAM,CAAC,QAAQ,CAAC,IAAI,GAAG,GAAG,CAAC;YAC7B,CAAC;iBAAM,CAAC;gBACN,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC;YACzC,CAAC;QACH,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAClB,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YACnB,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,IAAI,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC;QACxD,CAAC;IACH,CAAC,CAAC;IAEF,OAAO,CACL,cAAK,SAAS,EAAC,mDAAmD,YAChE,MAAC,IAAI,IAAC,SAAS,EAAC,iBAAiB,aAC/B,MAAC,UAAU,IAAC,SAAS,EAAC,aAAa,aACjC,cAAK,SAAS,EAAC,oFAAoF,YACjG,KAAC,WAAW,IAAC,SAAS,EAAC,sBAAsB,GAAG,GAC5C,EACN,KAAC,SAAS,cAAE,CAAC,CAAC,sBAAsB,CAAC,GAAa,EAClD,KAAC,eAAe,cACb,CAAC,CACA,iFAAiF,CAClF,GACe,IACP,EACb,KAAC,WAAW,cACV,MAAC,MAAM,IAAC,OAAO,EAAE,YAAY,EAAE,SAAS,EAAC,cAAc,aACrD,KAAC,WAAW,IAAC,SAAS,EAAC,QAAQ,GAAG,EACjC,CAAC,CAAC,2BAA2B,CAAC,IACxB,GACG,IACT,GACH,CACP,CAAC;AACJ,CAAC"}
@@ -0,0 +1,52 @@
1
+ {
2
+ "2FA Verified": "2FA Verified",
3
+ "General": "General",
4
+ "Continue with Passkey": "Continue with Passkey",
5
+ "Passkeys": "Passkeys",
6
+ "Use biometric authentication to sign in securely.": "Use biometric authentication to sign in securely.",
7
+ "Add new Passkey": "Add new Passkey",
8
+ "Passkey registered successfully!": "Passkey registered successfully!",
9
+ "Registration failed.": "Registration failed.",
10
+ "Logged in successfully!": "Logged in successfully!",
11
+ "Login failed.": "Login failed.",
12
+ "Unnamed Passkey": "Unnamed Passkey",
13
+ "Are you sure you want to delete this passkey?": "Are you sure you want to delete this passkey?",
14
+ "Passkey deleted.": "Passkey deleted.",
15
+ "Failed to delete.": "Failed to delete.",
16
+ "Passkey renamed.": "Passkey renamed.",
17
+ "Failed to rename.": "Failed to rename.",
18
+ "Rename Passkey": "Rename Passkey",
19
+ "Give this passkey a recognizable name.": "Give this passkey a recognizable name.",
20
+ "e.g. My Phone": "e.g. My Phone",
21
+ "Cancel": "Cancel",
22
+ "Save": "Save",
23
+ "Passkey Login Verification": "Passkey Login Verification",
24
+ "Require passkey verification after traditional login.": "Require passkey verification after traditional login.",
25
+ "Enable Passkey 2FA": "Enable Passkey 2FA",
26
+ "You must register at least one passkey to enable this feature.": "You must register at least one passkey to enable this feature.",
27
+ "Passkey 2FA enabled.": "Passkey 2FA enabled.",
28
+ "Passkey 2FA disabled.": "Passkey 2FA disabled.",
29
+ "Failed to update settings.": "Failed to update settings.",
30
+ "Passkey Verification": "Passkey Verification",
31
+ "To continue, please verify your identity using one of your registered passkeys.": "To continue, please verify your identity using one of your registered passkeys.",
32
+ "Authenticate with Passkey": "Authenticate with Passkey",
33
+ "Identity verified!": "Identity verified!",
34
+ "Security": "Security",
35
+ "Passkey Settings": "Passkey Settings",
36
+ "Failed to get login options": "Failed to get login options",
37
+ "Verification failed": "Verification failed",
38
+ "Verification failed.": "Verification failed.",
39
+ "Failed to get options": "Failed to get options",
40
+ "Settings saved successfully": "Settings saved successfully",
41
+ "Failed to save settings": "Failed to save settings",
42
+ "Passkey Configuration": "Passkey Configuration",
43
+ "Configure Relying Party settings for WebAuthn.": "Configure Relying Party settings for WebAuthn.",
44
+ "RP Name": "RP Name",
45
+ "A user-friendly name of the service.": "A user-friendly name of the service.",
46
+ "RP ID": "RP ID",
47
+ "The domain name where the service is hosted.": "The domain name where the service is hosted.",
48
+ "Origin": "Origin",
49
+ "The full origin of the service, including protocol and port.": "The full origin of the service, including protocol and port.",
50
+ "Saving...": "Saving...",
51
+ "Save Settings": "Save Settings"
52
+ }
@@ -0,0 +1,52 @@
1
+ {
2
+ "2FA Verified": "Zweryfikowano 2FA",
3
+ "General": "Ogólny",
4
+ "Continue with Passkey": "Kontynuuj za pomocą klucza",
5
+ "Passkeys": "Klucze",
6
+ "Use biometric authentication to sign in securely.": "Użyj uwierzytelniania biometrycznego, aby zalogować się bezpiecznie.",
7
+ "Add new Passkey": "Dodaj nowy klucz dostępu",
8
+ "Passkey registered successfully!": "Klucz został pomyślnie zarejestrowany!",
9
+ "Registration failed.": "Rejestracja nie powiodła się.",
10
+ "Logged in successfully!": "Zalogowano się pomyślnie!",
11
+ "Login failed.": "Logowanie nie powiodło się.",
12
+ "Unnamed Passkey": "Nienazwany klucz dostępu",
13
+ "Are you sure you want to delete this passkey?": "Czy na pewno chcesz usunąć to hasło?",
14
+ "Passkey deleted.": "Klucz został usunięty.",
15
+ "Failed to delete.": "Nie udało się usunąć.",
16
+ "Passkey renamed.": "Zmieniono nazwę klucza.",
17
+ "Failed to rename.": "Nie udało się zmienić nazwy.",
18
+ "Rename Passkey": "Zmień nazwę klucza",
19
+ "Give this passkey a recognizable name.": "Nadaj temu kluczowi rozpoznawalną nazwę.",
20
+ "e.g. My Phone": "np. Mój telefon",
21
+ "Cancel": "Anulować",
22
+ "Save": "Ratować",
23
+ "Passkey Login Verification": "Weryfikacja logowania przy użyciu klucza dostępu",
24
+ "Require passkey verification after traditional login.": "Wymagaj weryfikacji hasła po tradycyjnym logowaniu.",
25
+ "Enable Passkey 2FA": "Włącz klucz dostępu 2FA",
26
+ "You must register at least one passkey to enable this feature.": "Aby włączyć tę funkcję, musisz zarejestrować co najmniej jedno hasło.",
27
+ "Passkey 2FA enabled.": "Włączono klucz dostępu 2FA.",
28
+ "Passkey 2FA disabled.": "Klucz dostępu 2FA wyłączony.",
29
+ "Failed to update settings.": "Nie udało się zaktualizować ustawień.",
30
+ "Passkey Verification": "Weryfikacja klucza",
31
+ "To continue, please verify your identity using one of your registered passkeys.": "Aby kontynuować, zweryfikuj swoją tożsamość za pomocą jednego z zarejestrowanych kluczy.",
32
+ "Authenticate with Passkey": "Uwierzytelnij się za pomocą klucza",
33
+ "Identity verified!": "Tożsamość potwierdzona!",
34
+ "Security": "Bezpieczeństwo",
35
+ "Passkey Settings": "Ustawienia klucza dostępu",
36
+ "Failed to get login options": "Nie udało się uzyskać opcji logowania",
37
+ "Verification failed": "Weryfikacja nie powiodła się",
38
+ "Verification failed.": "Weryfikacja nie powiodła się.",
39
+ "Failed to get options": "Nie udało się pobrać opcji",
40
+ "Settings saved successfully": "Ustawienia zostały zapisane pomyślnie",
41
+ "Failed to save settings": "Nie udało się zapisać ustawień",
42
+ "Passkey Configuration": "Konfiguracja klucza dostępu",
43
+ "Configure Relying Party settings for WebAuthn.": "Skonfiguruj ustawienia jednostki zależnej dla WebAuthn.",
44
+ "RP Name": "Nazwa RP",
45
+ "A user-friendly name of the service.": "Przyjazna dla użytkownika nazwa usługi.",
46
+ "RP ID": "Identyfikator RP",
47
+ "The domain name where the service is hosted.": "Nazwa domeny, w której hostowana jest usługa.",
48
+ "Origin": "Pochodzenie",
49
+ "The full origin of the service, including protocol and port.": "Pełne pochodzenie usługi, w tym protokół i port.",
50
+ "Saving...": "Zapisano...",
51
+ "Save Settings": "Zapisz ustawienia"
52
+ }
package/manifest.json ADDED
@@ -0,0 +1,11 @@
1
+ {
2
+ "id": "auth-passkey-module",
3
+ "name": "Auth Passkey Module",
4
+ "version": "0.0.1",
5
+ "description": "Allows users to sign in using passkeys and two factor identity",
6
+ "enabled": true,
7
+ "system": false,
8
+ "dependencies": ["auth"],
9
+ "extends": ["auth"],
10
+ "isNpm": true
11
+ }
package/package.json ADDED
@@ -0,0 +1,45 @@
1
+ {
2
+ "name": "@vilio/auth-passkey-module",
3
+ "version": "0.0.2",
4
+ "description": "auth-passkey-module module for Vilio framework",
5
+ "main": "./dist/index.js",
6
+ "exports": {
7
+ "./package.json": "./package.json",
8
+ ".": "./dist/index.js",
9
+ "./client": "./dist/client.js"
10
+ },
11
+ "files": [
12
+ "dist",
13
+ "locales",
14
+ "manifest.json"
15
+ ],
16
+ "scripts": {
17
+ "release": "npm publish --access public --no-git-checks",
18
+ "clean": "rm -rf ./dist",
19
+ "dev": "tsc --watch",
20
+ "build": "tsc"
21
+ },
22
+ "dependencies": {
23
+ "@simplewebauthn/browser": "^13.3.0",
24
+ "@simplewebauthn/server": "^13.3.0",
25
+ "@vilio/modules": "^0.0.6",
26
+ "@vilio/ui": "^0.0.6",
27
+ "drizzle-orm": "1.0.0-beta.6-4414a19",
28
+ "lucide-react": "^0.475.0",
29
+ "sonner": "^2.0.7"
30
+ },
31
+ "devDependencies": {
32
+ "@types/react": "^19",
33
+ "@vilio/core": "^0.0.9",
34
+ "next": "16.1.6",
35
+ "react": "^19.0.0",
36
+ "typescript": "^5.3.3"
37
+ },
38
+ "peerDependencies": {
39
+ "@vilio/core": "^0.0.9",
40
+ "@vilio/intl": "^0.0.7",
41
+ "@vilio/ui": "^0.0.6",
42
+ "next": "16.1.6",
43
+ "react": "^19.0.0"
44
+ }
45
+ }