Skip to content

Commit aec7118

Browse files
authored
Merge pull request #25 from operacle/develop
feat: Auto logout after password change
2 parents 759c324 + a5ad5ee commit aec7118

File tree

14 files changed

+309
-358
lines changed

14 files changed

+309
-358
lines changed

README.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,8 @@ services:
8585
- [ ] Infrastructure Server Monitoring
8686
- [ ] Operational Status / Public Status Pages
8787
- [ ] Uptime monitoring (TCP, PING, DNS)
88-
- [ ] User Permission Roles & Service Group
88+
- [x] System Setting Panel and Mail Settings
89+
- [x] User Permission Roles
8990
- [ ] Notifications (Email/Slack/Discord/Signal)
9091
- [x] Open-source release with full documentation
9192

@@ -122,4 +123,8 @@ CheckCle is released under the MIT License.
122123

123124
---
124125

126+
## Star History
127+
128+
[![Star History Chart](https://api.star-history.com/svg?repos=operacle/checkcle&type=Date)](https://www.star-history.com/#operacle/checkcle&Date)
129+
125130
Stay informed, stay online, with CheckCle! 🌐

application/src/components/profile/ChangePasswordForm.tsx

Lines changed: 43 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
import { useState } from "react";
32
import { z } from "zod";
43
import { useForm } from "react-hook-form";
@@ -10,6 +9,7 @@ import { useToast } from "@/hooks/use-toast";
109
import { Eye, EyeOff } from "lucide-react";
1110
import { pb } from "@/lib/pocketbase";
1211
import { authService } from "@/services/authService";
12+
import { useNavigate } from "react-router-dom";
1313

1414
// Password change form schema
1515
const passwordFormSchema = z.object({
@@ -34,6 +34,7 @@ export function ChangePasswordForm({ userId }: ChangePasswordFormProps) {
3434
const [showConfirmPassword, setShowConfirmPassword] = useState(false);
3535

3636
const { toast } = useToast();
37+
const navigate = useNavigate();
3738

3839
const form = useForm<PasswordFormValues>({
3940
resolver: zodResolver(passwordFormSchema),
@@ -44,12 +45,35 @@ export function ChangePasswordForm({ userId }: ChangePasswordFormProps) {
4445
},
4546
});
4647

48+
// Function to determine which collection the user belongs to
49+
const getUserCollection = async (userId: string): Promise<string> => {
50+
try {
51+
// First try to find the user in the regular users collection
52+
await pb.collection('users').getOne(userId);
53+
return 'users';
54+
} catch (error) {
55+
try {
56+
// If not found, try the superadmin collection
57+
await pb.collection('_superusers').getOne(userId);
58+
return '_superusers';
59+
} catch (error) {
60+
throw new Error('User not found in any collection');
61+
}
62+
}
63+
};
64+
4765
async function onSubmit(data: PasswordFormValues) {
4866
setIsSubmitting(true);
4967

5068
try {
69+
console.log("Starting password change for user:", userId);
70+
71+
// Determine which collection the user belongs to
72+
const collection = await getUserCollection(userId);
73+
console.log("User found in collection:", collection);
74+
5175
// PocketBase requires the old password along with the new one
52-
await pb.collection('users').update(userId, {
76+
await pb.collection(collection).update(userId, {
5377
oldPassword: data.currentPassword,
5478
password: data.newPassword,
5579
passwordConfirm: data.confirmPassword,
@@ -60,17 +84,31 @@ export function ChangePasswordForm({ userId }: ChangePasswordFormProps) {
6084

6185
toast({
6286
title: "Password updated",
63-
description: "Your password has been changed successfully.",
87+
description: "Your password has been changed successfully. You will be logged out in 3 seconds for security.",
6488
});
6589

6690
// Reset the form
6791
form.reset();
92+
93+
// Auto logout after successful password change
94+
setTimeout(() => {
95+
console.log("Auto logout after password change");
96+
authService.logout();
97+
navigate("/login");
98+
}, 3000);
99+
68100
} catch (error) {
69101
console.error("Password change error:", error);
70102

71103
let errorMessage = "Failed to update password. Please try again.";
72104
if (error instanceof Error) {
73-
errorMessage = error.message;
105+
if (error.message.includes("Failed to authenticate")) {
106+
errorMessage = "Current password is incorrect. Please try again.";
107+
} else if (error.message.includes("User not found")) {
108+
errorMessage = "User account not found. Please contact your administrator.";
109+
} else {
110+
errorMessage = error.message;
111+
}
74112
}
75113

76114
toast({
@@ -188,4 +226,4 @@ export function ChangePasswordForm({ userId }: ChangePasswordFormProps) {
188226
</form>
189227
</Form>
190228
);
191-
}
229+
}

application/src/components/settings/general/SystemSettingsTab.tsx

Lines changed: 1 addition & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11

22
import React from 'react';
33
import { Input } from "@/components/ui/input";
4-
import { Switch } from "@/components/ui/switch";
54
import { FormControl, FormField, FormItem, FormLabel } from "@/components/ui/form";
65
import { useLanguage } from "@/contexts/LanguageContext";
76
import { SettingsTabProps } from "./types";
@@ -48,7 +47,7 @@ const SystemSettingsTab: React.FC<SettingsTabProps> = ({ form, isEditing, settin
4847
<Input
4948
{...field}
5049
disabled={!isEditing}
51-
placeholder="https://localhost:8090"
50+
placeholder="https://pb-api.k8sops.asia"
5251
className="bg-background border-input text-foreground placeholder:text-muted-foreground disabled:bg-muted disabled:text-muted-foreground"
5352
/>
5453
</FormControl>
@@ -57,72 +56,6 @@ const SystemSettingsTab: React.FC<SettingsTabProps> = ({ form, isEditing, settin
5756
/>
5857
</div>
5958
</div>
60-
61-
<div>
62-
<FormField
63-
control={form.control}
64-
name="meta.senderName"
65-
render={({ field }) => (
66-
<FormItem>
67-
<FormLabel className="text-sm font-medium text-foreground">
68-
{t("senderName", "settings")}
69-
</FormLabel>
70-
<FormControl>
71-
<Input
72-
{...field}
73-
disabled={!isEditing}
74-
placeholder="System Administrator"
75-
className="bg-background border-input text-foreground placeholder:text-muted-foreground disabled:bg-muted disabled:text-muted-foreground"
76-
/>
77-
</FormControl>
78-
</FormItem>
79-
)}
80-
/>
81-
</div>
82-
83-
<div>
84-
<FormField
85-
control={form.control}
86-
name="meta.senderAddress"
87-
render={({ field }) => (
88-
<FormItem>
89-
<FormLabel className="text-sm font-medium text-foreground">
90-
{t("senderEmail", "settings")}
91-
</FormLabel>
92-
<FormControl>
93-
<Input
94-
{...field}
95-
disabled={!isEditing}
96-
placeholder="admin@example.com"
97-
type="email"
98-
className="bg-background border-input text-foreground placeholder:text-muted-foreground disabled:bg-muted disabled:text-muted-foreground"
99-
/>
100-
</FormControl>
101-
</FormItem>
102-
)}
103-
/>
104-
</div>
105-
106-
<div className="flex items-center space-x-3 pt-4">
107-
<FormField
108-
control={form.control}
109-
name="meta.hideControls"
110-
render={({ field }) => (
111-
<FormItem className="flex flex-row items-center space-x-3 space-y-0">
112-
<FormControl>
113-
<Switch
114-
checked={field.value}
115-
onCheckedChange={field.onChange}
116-
disabled={!isEditing}
117-
/>
118-
</FormControl>
119-
<FormLabel className="text-sm font-medium text-foreground cursor-pointer">
120-
{t("hideControls", "settings")}
121-
</FormLabel>
122-
</FormItem>
123-
)}
124-
/>
125-
</div>
12659
</div>
12760
);
12861
};

application/src/translations/de/about.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ export const aboutTranslations: AboutTranslations = {
1212
viewDocumentation: "Dokumentation ansehen",
1313
followOnX: "Auf X folgen",
1414
joinDiscord: "Discord beitreten",
15-
quickActions: "Quick Actions",
16-
quickActionsDescription: "Access common monitoring operations and features quickly. Select an action below to get started.",
17-
quickTips: "Quick Tips",
15+
quickActions: "Schnelle Aktionen",
16+
quickActionsDescription: "Greifen Sie schnell auf gängige Überwachungsvorgänge und -funktionen zu. Wählen Sie unten eine Aktion aus, um loszulegen.",
17+
quickTips: "Schnelle Tipps",
1818
};
1919

2020

application/src/translations/de/common.ts

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,19 @@ export const commonTranslations: CommonTranslations = {
1111
goodMorning: "Guten Morgen",
1212
goodAfternoon: "Guten Nachmittag",
1313
goodEvening: "Guten Abend",
14-
profile: "Profile",
15-
settings: "Settings",
16-
documentation: "Documentation",
17-
notifications: "Notifications",
18-
close: "Close",
19-
cancel: "Cancel",
20-
view: "View",
21-
edit: "Edit",
22-
delete: "Delete",
14+
profile: "Profil",
15+
settings: "Einstellungen",
16+
documentation: "Dokumentation",
17+
notifications: "Benachrichtigungen",
18+
close: "Schließen",
19+
cancel: "Abbrechen",
20+
view: "Anzeigen",
21+
edit: "Bearbeiten",
22+
delete: "Löschen",
2323
status: "Status",
24-
time: "Time",
25-
title: "Title",
26-
description: "Description",
27-
success: "Success",
28-
error: "Error",
24+
time: "Zeit",
25+
title: "Titel",
26+
description: "Beschreibung",
27+
success: "Erfolg",
28+
error: "Fehler",
2929
};
Lines changed: 50 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,54 @@
1-
21
import { IncidentTranslations } from '../types/incident';
32

43
export const incidentTranslations: IncidentTranslations = {
5-
incidentManagement: 'Incident Management',
6-
incidentsManagementDesc: 'Track and manage service incidents and their resolutions',
7-
unresolvedIncidents: 'Unresolved',
8-
resolvedIncidents: 'Resolved',
9-
activeIncidents: 'Active Incidents',
10-
criticalIssues: 'Critical Issues',
11-
avgResolutionTime: 'Avg. Resolution Time',
12-
noIncidents: 'No Active Incidents',
13-
createIncident: 'Create Incident',
14-
investigating: 'Investigating',
15-
identified: 'Identified',
16-
monitoring: 'Monitoring',
17-
resolved: 'Resolved',
18-
scheduleIncidentManagement: 'Schedule & Incident Management',
19-
incidentName: 'Incident Name',
20-
incidentStatus: 'Incident Status',
21-
highPriority: 'High Priority',
22-
configurationSettings: 'Configuration Settings',
23-
incidentCreatedSuccess: 'Incident created successfully',
24-
basicInfo: 'Basic Information',
25-
serviceId: 'Service ID',
26-
assignedTo: 'Assigned To',
27-
unassigned: 'Unassigned',
28-
timeline: 'Timeline',
29-
incidentTime: 'Incident Time',
30-
resolutionTime: 'Resolution Time',
31-
systems: 'Systems',
32-
noSystems: 'No systems affected',
33-
impactAnalysis: 'Impact Analysis',
34-
rootCause: 'Root Cause',
35-
resolutionSteps: 'Resolution Steps',
36-
lessonsLearned: 'Lessons Learned',
37-
resolutionDetails: 'Resolution Details',
38-
assignment: 'Assignment',
39-
download: 'Download',
40-
downloadPdf: 'Download PDF',
41-
print: 'Print',
42-
confidentialNote: 'This document is confidential and intended for internal use only.',
43-
generatedOn: 'Generated on',
44-
enterResolutionSteps: 'Enter steps taken to resolve the incident',
45-
enterLessonsLearned: 'Enter lessons learned from this incident',
46-
editIncident: 'Edit Incident',
47-
editIncidentDesc: 'Update details for this incident',
48-
updating: 'Updating...',
49-
update: 'Update',
50-
create: 'Create',
51-
creating: 'Creating...',
52-
configuration: 'Configuration',
53-
failedToUpdateStatus: 'Failed to update status',
54-
inProgress: 'In Progress',
4+
incidentManagement: 'Vorfallmanagement',
5+
incidentsManagementDesc: 'Verfolgen und Verwalten von Servicevorfällen und deren Lösungen',
6+
unresolvedIncidents: 'Ungelöst',
7+
resolvedIncidents: 'Gelöst',
8+
activeIncidents: 'Aktive Vorfälle',
9+
criticalIssues: 'Kritische Probleme',
10+
avgResolutionTime: 'Durchschn. Lösungszeit',
11+
noIncidents: 'Keine aktiven Vorfälle',
12+
createIncident: 'Vorfall erstellen',
13+
investigating: 'Untersuchung läuft',
14+
identified: 'Identifiziert',
15+
monitoring: 'Überwachung',
16+
resolved: 'Gelöst',
17+
scheduleIncidentManagement: 'Zeitplanung & Vorfallmanagement',
18+
incidentName: 'Vorfallname',
19+
incidentStatus: 'Vorfallstatus',
20+
highPriority: 'Hohe Priorität',
21+
configurationSettings: 'Konfigurationseinstellungen',
22+
incidentCreatedSuccess: 'Vorfall erfolgreich erstellt',
23+
basicInfo: 'Grundinformationen',
24+
serviceId: 'Service-ID',
25+
assignedTo: 'Zugewiesen an',
26+
unassigned: 'Nicht zugewiesen',
27+
timeline: 'Zeitverlauf',
28+
incidentTime: 'Vorfallszeit',
29+
resolutionTime: 'Lösungszeit',
30+
systems: 'Systeme',
31+
noSystems: 'Keine betroffenen Systeme',
32+
impactAnalysis: 'Auswirkungsanalyse',
33+
rootCause: 'Ursache',
34+
resolutionSteps: 'Lösungsschritte',
35+
lessonsLearned: 'Erkenntnisse',
36+
resolutionDetails: 'Details zur Lösung',
37+
assignment: 'Zuweisung',
38+
download: 'Herunterladen',
39+
downloadPdf: 'PDF herunterladen',
40+
print: 'Drucken',
41+
confidentialNote: 'Dieses Dokument ist vertraulich und nur für den internen Gebrauch bestimmt.',
42+
generatedOn: 'Erstellt am',
43+
enterResolutionSteps: 'Geben Sie die zur Lösung ergriffenen Schritte ein',
44+
enterLessonsLearned: 'Geben Sie die aus diesem Vorfall gewonnenen Erkenntnisse ein',
45+
editIncident: 'Vorfall bearbeiten',
46+
editIncidentDesc: 'Details zu diesem Vorfall aktualisieren',
47+
updating: 'Aktualisiere...',
48+
update: 'Aktualisieren',
49+
create: 'Erstellen',
50+
creating: 'Erstelle...',
51+
configuration: 'Konfiguration',
52+
failedToUpdateStatus: 'Fehler beim Aktualisieren des Status',
53+
inProgress: 'In Bearbeitung',
5554
};

0 commit comments

Comments
 (0)