diff --git a/web-app/app/[locale]/email/verify/[id]/EmailVerifyPage.tsx b/web-app/app/[locale]/email/verify/[id]/EmailVerifyPage.tsx
index 48cc4a7..a48de4a 100644
--- a/web-app/app/[locale]/email/verify/[id]/EmailVerifyPage.tsx
+++ b/web-app/app/[locale]/email/verify/[id]/EmailVerifyPage.tsx
@@ -7,9 +7,10 @@ import { CheckCircleIcon } from '@heroicons/react/24/outline';
interface EmailVerifyPageProps {
shareId: string;
+ isPending: boolean;
}
-export default function EmailVerifyPage({ shareId }: EmailVerifyPageProps) {
+export default function EmailVerifyPage({ shareId, isPending }: EmailVerifyPageProps) {
const t = useTranslations('email-verify-page');
const [isVerifying, setIsVerifying] = useState(false);
const [isVerified, setIsVerified] = useState(false);
@@ -61,6 +62,17 @@ export default function EmailVerifyPage({ shareId }: EmailVerifyPageProps) {
);
}
+ if (!isPending) {
+ return (
+
diff --git a/web-app/app/[locale]/email/verify/[id]/page.tsx b/web-app/app/[locale]/email/verify/[id]/page.tsx
index e7d4360..3b4cc9d 100644
--- a/web-app/app/[locale]/email/verify/[id]/page.tsx
+++ b/web-app/app/[locale]/email/verify/[id]/page.tsx
@@ -1,12 +1,44 @@
import { Suspense } from 'react';
import EmailVerifyPage from './EmailVerifyPage';
import { Main } from '@/app/ui/Main';
+import { getDbClient } from '@/app/lib/dbClient';
+import { BillingLocation, EmailStatus } from '@/app/lib/db-types';
+import { extractShareId, validateShareChecksum } from '@/app/lib/shareChecksum';
+import { notFound } from 'next/navigation';
export default async function Page({ params: { id } }: { params: { id: string } }) {
+ // Extract and validate share ID
+ const extracted = extractShareId(id);
+ if (!extracted) {
+ notFound();
+ }
+
+ const { locationId, checksum } = extracted;
+
+ // Validate checksum
+ if (!validateShareChecksum(locationId, checksum)) {
+ notFound();
+ }
+
+ // Fetch location to check email status
+ const dbClient = await getDbClient();
+ const location = await dbClient.collection("lokacije")
+ .findOne(
+ { _id: locationId },
+ { projection: { tenantEmail: 1, tenantEmailStatus: 1 } }
+ );
+
+ if (!location || !location.tenantEmail) {
+ notFound();
+ }
+
+ // Check if email is pending verification
+ const isPending = location.tenantEmailStatus === EmailStatus.VerificationPending;
+
return (
Loading...
}>
-
+
);
diff --git a/web-app/messages/en.json b/web-app/messages/en.json
index 330f352..341bc2f 100644
--- a/web-app/messages/en.json
+++ b/web-app/messages/en.json
@@ -455,6 +455,10 @@
"error": {
"title": "Verification Failed",
"unknown": "An error occurred during verification. Please try again or contact your landlord."
+ },
+ "not-allowed": {
+ "title": "Action not possible",
+ "message": "The selected action cannot be performed or the passed information is invalid."
}
},
"email-unsubscribe-page": {
diff --git a/web-app/messages/hr.json b/web-app/messages/hr.json
index 5fd356e..6030509 100644
--- a/web-app/messages/hr.json
+++ b/web-app/messages/hr.json
@@ -452,6 +452,10 @@
"error": {
"title": "Potvrda Nije Uspjela",
"unknown": "Došlo je do greške prilikom potvrde. Molimo pokušajte ponovno ili kontaktirajte vašeg vlasnika nekretnine."
+ },
+ "not-allowed": {
+ "title": "Akcija nije moguća",
+ "message": "Odabrana akcija nije moguća ili zadani podaci nisu ispravni."
}
},
"email-unsubscribe-page": {