More fixes and linting
This commit is contained in:
parent
b120071762
commit
ff48b7c464
6 changed files with 1071 additions and 1101 deletions
|
|
@ -116,10 +116,7 @@ export default function LoginPage() {
|
||||||
// Show 2FA verification form
|
// Show 2FA verification form
|
||||||
if (pendingSessionId) {
|
if (pendingSessionId) {
|
||||||
return (
|
return (
|
||||||
<AuthLayout
|
<AuthLayout title="Two-Factor Authentication" description="Enter the 6-digit code from your authenticator app">
|
||||||
title="Two-Factor Authentication"
|
|
||||||
description="Enter the 6-digit code from your authenticator app"
|
|
||||||
>
|
|
||||||
<form onSubmit={handleTwoFactorSubmit} className="space-y-4">
|
<form onSubmit={handleTwoFactorSubmit} className="space-y-4">
|
||||||
<div className="grid gap-2">
|
<div className="grid gap-2">
|
||||||
<Label htmlFor="2fa-code">Authentication Code</Label>
|
<Label htmlFor="2fa-code">Authentication Code</Label>
|
||||||
|
|
|
||||||
|
|
@ -150,10 +150,14 @@ export default function Settings({ loaderData }: Route.ComponentProps) {
|
||||||
}, 1500);
|
}, 1500);
|
||||||
} else {
|
} else {
|
||||||
toast.error("Failed to enable 2FA", { description: data.message });
|
toast.error("Failed to enable 2FA", { description: data.message });
|
||||||
|
setEnable2faDialogOpen(false);
|
||||||
|
resetEnable2faDialog();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onError: (error) => {
|
onError: (error) => {
|
||||||
toast.error("Failed to enable 2FA", { description: error.message });
|
toast.error("Failed to enable 2FA", { description: error.message });
|
||||||
|
setEnable2faDialogOpen(false);
|
||||||
|
resetEnable2faDialog();
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -169,10 +173,14 @@ export default function Settings({ loaderData }: Route.ComponentProps) {
|
||||||
}, 1500);
|
}, 1500);
|
||||||
} else {
|
} else {
|
||||||
toast.error("Failed to disable 2FA", { description: data.message });
|
toast.error("Failed to disable 2FA", { description: data.message });
|
||||||
|
setDisable2faDialogOpen(false);
|
||||||
|
resetDisable2faDialog();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onError: (error) => {
|
onError: (error) => {
|
||||||
toast.error("Failed to disable 2FA", { description: error.message });
|
toast.error("Failed to disable 2FA", { description: error.message });
|
||||||
|
setDisable2faDialogOpen(false);
|
||||||
|
resetDisable2faDialog();
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -350,10 +358,20 @@ export default function Settings({ loaderData }: Route.ComponentProps) {
|
||||||
<CardTitle className="flex items-center gap-2">
|
<CardTitle className="flex items-center gap-2">
|
||||||
<Shield className="size-5" />
|
<Shield className="size-5" />
|
||||||
Two-Factor Authentication
|
Two-Factor Authentication
|
||||||
{twoFactorStatus.data && (
|
{twoFactorStatus.isLoading ? (
|
||||||
<Badge variant={twoFactorStatus.data.enabled ? "success" : "secondary"} className="ml-2">
|
<Badge variant="secondary" className="ml-2">
|
||||||
{twoFactorStatus.data.enabled ? "Enabled" : "Disabled"}
|
Loading...
|
||||||
</Badge>
|
</Badge>
|
||||||
|
) : twoFactorStatus.isError ? (
|
||||||
|
<Badge variant="secondary" className="ml-2">
|
||||||
|
Status unavailable
|
||||||
|
</Badge>
|
||||||
|
) : (
|
||||||
|
twoFactorStatus.data && (
|
||||||
|
<Badge variant={twoFactorStatus.data.enabled ? "success" : "secondary"} className="ml-2">
|
||||||
|
{twoFactorStatus.data.enabled ? "Enabled" : "Disabled"}
|
||||||
|
</Badge>
|
||||||
|
)
|
||||||
)}
|
)}
|
||||||
</CardTitle>
|
</CardTitle>
|
||||||
<CardDescription className="mt-1.5">Add an extra layer of security to your account</CardDescription>
|
<CardDescription className="mt-1.5">Add an extra layer of security to your account</CardDescription>
|
||||||
|
|
@ -364,7 +382,12 @@ export default function Settings({ loaderData }: Route.ComponentProps) {
|
||||||
authenticator app when logging in.
|
authenticator app when logging in.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
{twoFactorStatus.data?.enabled ? (
|
{twoFactorStatus.isLoading || twoFactorStatus.isError ? (
|
||||||
|
<Button variant="outline" disabled>
|
||||||
|
<Shield size={16} className="mr-2" />
|
||||||
|
{twoFactorStatus.isLoading ? "Loading..." : "Status unavailable"}
|
||||||
|
</Button>
|
||||||
|
) : twoFactorStatus.data?.enabled ? (
|
||||||
<Dialog
|
<Dialog
|
||||||
open={disable2faDialogOpen}
|
open={disable2faDialogOpen}
|
||||||
onOpenChange={(open) => {
|
onOpenChange={(open) => {
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,216 +1,216 @@
|
||||||
{
|
{
|
||||||
"version": "7",
|
"version": "7",
|
||||||
"dialect": "sqlite",
|
"dialect": "sqlite",
|
||||||
"entries": [
|
"entries": [
|
||||||
{
|
{
|
||||||
"idx": 0,
|
"idx": 0,
|
||||||
"version": "6",
|
"version": "6",
|
||||||
"when": 1755765658194,
|
"when": 1755765658194,
|
||||||
"tag": "0000_known_madelyne_pryor",
|
"tag": "0000_known_madelyne_pryor",
|
||||||
"breakpoints": true
|
"breakpoints": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"idx": 1,
|
"idx": 1,
|
||||||
"version": "6",
|
"version": "6",
|
||||||
"when": 1755775437391,
|
"when": 1755775437391,
|
||||||
"tag": "0001_far_frank_castle",
|
"tag": "0001_far_frank_castle",
|
||||||
"breakpoints": true
|
"breakpoints": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"idx": 2,
|
"idx": 2,
|
||||||
"version": "6",
|
"version": "6",
|
||||||
"when": 1756930554198,
|
"when": 1756930554198,
|
||||||
"tag": "0002_cheerful_randall",
|
"tag": "0002_cheerful_randall",
|
||||||
"breakpoints": true
|
"breakpoints": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"idx": 3,
|
"idx": 3,
|
||||||
"version": "6",
|
"version": "6",
|
||||||
"when": 1758653407064,
|
"when": 1758653407064,
|
||||||
"tag": "0003_mature_hellcat",
|
"tag": "0003_mature_hellcat",
|
||||||
"breakpoints": true
|
"breakpoints": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"idx": 4,
|
"idx": 4,
|
||||||
"version": "6",
|
"version": "6",
|
||||||
"when": 1758961535488,
|
"when": 1758961535488,
|
||||||
"tag": "0004_wealthy_tomas",
|
"tag": "0004_wealthy_tomas",
|
||||||
"breakpoints": true
|
"breakpoints": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"idx": 5,
|
"idx": 5,
|
||||||
"version": "6",
|
"version": "6",
|
||||||
"when": 1759416698274,
|
"when": 1759416698274,
|
||||||
"tag": "0005_simple_alice",
|
"tag": "0005_simple_alice",
|
||||||
"breakpoints": true
|
"breakpoints": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"idx": 6,
|
"idx": 6,
|
||||||
"version": "6",
|
"version": "6",
|
||||||
"when": 1760734377440,
|
"when": 1760734377440,
|
||||||
"tag": "0006_secret_micromacro",
|
"tag": "0006_secret_micromacro",
|
||||||
"breakpoints": true
|
"breakpoints": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"idx": 7,
|
"idx": 7,
|
||||||
"version": "6",
|
"version": "6",
|
||||||
"when": 1761224911352,
|
"when": 1761224911352,
|
||||||
"tag": "0007_watery_sersi",
|
"tag": "0007_watery_sersi",
|
||||||
"breakpoints": true
|
"breakpoints": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"idx": 8,
|
"idx": 8,
|
||||||
"version": "6",
|
"version": "6",
|
||||||
"when": 1761414054481,
|
"when": 1761414054481,
|
||||||
"tag": "0008_silent_lady_bullseye",
|
"tag": "0008_silent_lady_bullseye",
|
||||||
"breakpoints": true
|
"breakpoints": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"idx": 9,
|
"idx": 9,
|
||||||
"version": "6",
|
"version": "6",
|
||||||
"when": 1762095226041,
|
"when": 1762095226041,
|
||||||
"tag": "0009_little_adam_warlock",
|
"tag": "0009_little_adam_warlock",
|
||||||
"breakpoints": true
|
"breakpoints": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"idx": 10,
|
"idx": 10,
|
||||||
"version": "6",
|
"version": "6",
|
||||||
"when": 1762610065889,
|
"when": 1762610065889,
|
||||||
"tag": "0010_perfect_proemial_gods",
|
"tag": "0010_perfect_proemial_gods",
|
||||||
"breakpoints": true
|
"breakpoints": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"idx": 11,
|
"idx": 11,
|
||||||
"version": "6",
|
"version": "6",
|
||||||
"when": 1763644043601,
|
"when": 1763644043601,
|
||||||
"tag": "0011_familiar_stone_men",
|
"tag": "0011_familiar_stone_men",
|
||||||
"breakpoints": true
|
"breakpoints": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"idx": 12,
|
"idx": 12,
|
||||||
"version": "6",
|
"version": "6",
|
||||||
"when": 1764100562084,
|
"when": 1764100562084,
|
||||||
"tag": "0012_add_short_ids",
|
"tag": "0012_add_short_ids",
|
||||||
"breakpoints": true
|
"breakpoints": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"idx": 13,
|
"idx": 13,
|
||||||
"version": "6",
|
"version": "6",
|
||||||
"when": 1764182159797,
|
"when": 1764182159797,
|
||||||
"tag": "0013_elite_sprite",
|
"tag": "0013_elite_sprite",
|
||||||
"breakpoints": true
|
"breakpoints": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"idx": 14,
|
"idx": 14,
|
||||||
"version": "6",
|
"version": "6",
|
||||||
"when": 1764182405089,
|
"when": 1764182405089,
|
||||||
"tag": "0014_wild_echo",
|
"tag": "0014_wild_echo",
|
||||||
"breakpoints": true
|
"breakpoints": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"idx": 15,
|
"idx": 15,
|
||||||
"version": "6",
|
"version": "6",
|
||||||
"when": 1764182465287,
|
"when": 1764182465287,
|
||||||
"tag": "0015_jazzy_sersi",
|
"tag": "0015_jazzy_sersi",
|
||||||
"breakpoints": true
|
"breakpoints": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"idx": 16,
|
"idx": 16,
|
||||||
"version": "6",
|
"version": "6",
|
||||||
"when": 1764194697035,
|
"when": 1764194697035,
|
||||||
"tag": "0016_fix-timestamps-to-ms",
|
"tag": "0016_fix-timestamps-to-ms",
|
||||||
"breakpoints": true
|
"breakpoints": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"idx": 17,
|
"idx": 17,
|
||||||
"version": "6",
|
"version": "6",
|
||||||
"when": 1764357897219,
|
"when": 1764357897219,
|
||||||
"tag": "0017_fix-compression-modes",
|
"tag": "0017_fix-compression-modes",
|
||||||
"breakpoints": true
|
"breakpoints": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"idx": 18,
|
"idx": 18,
|
||||||
"version": "6",
|
"version": "6",
|
||||||
"when": 1764794371040,
|
"when": 1764794371040,
|
||||||
"tag": "0018_breezy_invaders",
|
"tag": "0018_breezy_invaders",
|
||||||
"breakpoints": true
|
"breakpoints": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"idx": 19,
|
"idx": 19,
|
||||||
"version": "6",
|
"version": "6",
|
||||||
"when": 1764839917446,
|
"when": 1764839917446,
|
||||||
"tag": "0019_secret_nomad",
|
"tag": "0019_secret_nomad",
|
||||||
"breakpoints": true
|
"breakpoints": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"idx": 20,
|
"idx": 20,
|
||||||
"version": "6",
|
"version": "6",
|
||||||
"when": 1764847918249,
|
"when": 1764847918249,
|
||||||
"tag": "0020_even_dexter_bennett",
|
"tag": "0020_even_dexter_bennett",
|
||||||
"breakpoints": true
|
"breakpoints": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"idx": 21,
|
"idx": 21,
|
||||||
"version": "6",
|
"version": "6",
|
||||||
"when": 1765307881092,
|
"when": 1765307881092,
|
||||||
"tag": "0021_steady_viper",
|
"tag": "0021_steady_viper",
|
||||||
"breakpoints": true
|
"breakpoints": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"idx": 22,
|
"idx": 22,
|
||||||
"version": "6",
|
"version": "6",
|
||||||
"when": 1765794552191,
|
"when": 1765794552191,
|
||||||
"tag": "0022_woozy_shen",
|
"tag": "0022_woozy_shen",
|
||||||
"breakpoints": true
|
"breakpoints": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"idx": 23,
|
"idx": 23,
|
||||||
"version": "6",
|
"version": "6",
|
||||||
"when": 1766320570509,
|
"when": 1766320570509,
|
||||||
"tag": "0023_special_thor",
|
"tag": "0023_special_thor",
|
||||||
"breakpoints": true
|
"breakpoints": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"idx": 24,
|
"idx": 24,
|
||||||
"version": "6",
|
"version": "6",
|
||||||
"when": 1766325504548,
|
"when": 1766325504548,
|
||||||
"tag": "0024_schedules-one-fs",
|
"tag": "0024_schedules-one-fs",
|
||||||
"breakpoints": true
|
"breakpoints": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"idx": 25,
|
"idx": 25,
|
||||||
"version": "6",
|
"version": "6",
|
||||||
"when": 1766431021321,
|
"when": 1766431021321,
|
||||||
"tag": "0025_remarkable_pete_wisdom",
|
"tag": "0025_remarkable_pete_wisdom",
|
||||||
"breakpoints": true
|
"breakpoints": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"idx": 26,
|
"idx": 26,
|
||||||
"version": "6",
|
"version": "6",
|
||||||
"when": 1766765013108,
|
"when": 1766765013108,
|
||||||
"tag": "0026_migrate-local-repo-paths",
|
"tag": "0026_migrate-local-repo-paths",
|
||||||
"breakpoints": true
|
"breakpoints": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"idx": 27,
|
"idx": 27,
|
||||||
"version": "6",
|
"version": "6",
|
||||||
"when": 1766778073418,
|
"when": 1766778073418,
|
||||||
"tag": "0027_careful_cammi",
|
"tag": "0027_careful_cammi",
|
||||||
"breakpoints": true
|
"breakpoints": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"idx": 28,
|
"idx": 28,
|
||||||
"version": "6",
|
"version": "6",
|
||||||
"when": 1766778162985,
|
"when": 1766778162985,
|
||||||
"tag": "0028_third_amazoness",
|
"tag": "0028_third_amazoness",
|
||||||
"breakpoints": true
|
"breakpoints": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"idx": 29,
|
"idx": 29,
|
||||||
"version": "6",
|
"version": "6",
|
||||||
"when": 1767366633340,
|
"when": 1767366633340,
|
||||||
"tag": "0029_demonic_namor",
|
"tag": "0029_demonic_namor",
|
||||||
"breakpoints": true
|
"breakpoints": true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,22 +34,20 @@ const disableTwoFactor = async (username: string): Promise<void> => {
|
||||||
console.log(" All existing sessions have been invalidated.");
|
console.log(" All existing sessions have been invalidated.");
|
||||||
};
|
};
|
||||||
|
|
||||||
export const twoFactorCommand = new Command("2fa")
|
export const twoFactorCommand = new Command("2fa").description("Two-factor authentication recovery").addCommand(
|
||||||
.description("Two-factor authentication recovery")
|
new Command("disable")
|
||||||
.addCommand(
|
.description("Disable 2FA for a user (recovery method when authenticator access is lost)")
|
||||||
new Command("disable")
|
.requiredOption("-u, --username <username>", "Username of the account")
|
||||||
.description("Disable 2FA for a user (recovery method when authenticator access is lost)")
|
.action(async (options) => {
|
||||||
.requiredOption("-u, --username <username>", "Username of the account")
|
console.log("\n🔐 Zerobyte Two-Factor Authentication Recovery\n");
|
||||||
.action(async (options) => {
|
|
||||||
console.log("\n🔐 Zerobyte Two-Factor Authentication Recovery\n");
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await disableTwoFactor(options.username);
|
await disableTwoFactor(options.username);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`\n❌ ${error instanceof Error ? error.message : "Unknown error"}`);
|
console.error(`\n❌ ${error instanceof Error ? error.message : "Unknown error"}`);
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
process.exit(0);
|
process.exit(0);
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import { authService } from "../modules/auth/auth.service";
|
||||||
|
|
||||||
export class CleanupSessionsJob extends Job {
|
export class CleanupSessionsJob extends Job {
|
||||||
async run() {
|
async run() {
|
||||||
authService.cleanupExpiredSessions();
|
await authService.cleanupExpiredSessions();
|
||||||
authService.cleanupExpiredPending2faSessions();
|
authService.cleanupExpiredPending2faSessions();
|
||||||
|
|
||||||
return { done: true, timestamp: new Date() };
|
return { done: true, timestamp: new Date() };
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue