diff --git a/web-app/app/[locale]/email/unsubscribe/[id]/EmailUnsubscribePage.tsx b/web-app/app/[locale]/email/unsubscribe/[id]/EmailUnsubscribePage.tsx
index ac3eb0b..a57dcf1 100644
--- a/web-app/app/[locale]/email/unsubscribe/[id]/EmailUnsubscribePage.tsx
+++ b/web-app/app/[locale]/email/unsubscribe/[id]/EmailUnsubscribePage.tsx
@@ -7,9 +7,10 @@ import { CheckCircleIcon } from '@heroicons/react/24/outline';
interface EmailUnsubscribePageProps {
shareId: string;
+ isVerified: boolean;
}
-export default function EmailUnsubscribePage({ shareId }: EmailUnsubscribePageProps) {
+export default function EmailUnsubscribePage({ shareId, isVerified }: EmailUnsubscribePageProps) {
const t = useTranslations('email-unsubscribe-page');
const [isUnsubscribing, setIsUnsubscribing] = useState(false);
const [isUnsubscribed, setIsUnsubscribed] = useState(false);
@@ -61,6 +62,17 @@ export default function EmailUnsubscribePage({ shareId }: EmailUnsubscribePagePr
);
}
+ if (!isVerified) {
+ return (
+
diff --git a/web-app/app/[locale]/email/unsubscribe/[id]/page.tsx b/web-app/app/[locale]/email/unsubscribe/[id]/page.tsx
index 4300d9e..5c7c5a2 100644
--- a/web-app/app/[locale]/email/unsubscribe/[id]/page.tsx
+++ b/web-app/app/[locale]/email/unsubscribe/[id]/page.tsx
@@ -1,12 +1,44 @@
import { Suspense } from 'react';
import EmailUnsubscribePage from './EmailUnsubscribePage';
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 verified
+ const isVerified = location.tenantEmailStatus === EmailStatus.Verified;
+
return (
Loading...
}>
-
+
);
diff --git a/web-app/messages/en.json b/web-app/messages/en.json
index a4fb54c..31a338d 100644
--- a/web-app/messages/en.json
+++ b/web-app/messages/en.json
@@ -482,6 +482,10 @@
"error": {
"title": "Unsubscribe Failed",
"unknown": "An error occurred while unsubscribing. Please try again or contact your landlord."
+ },
+ "not-allowed": {
+ "title": "Action Not Allowed",
+ "message": "You can only unsubscribe from verified email addresses. This email address has not been verified yet or has already been unsubscribed."
}
},
"privacy-policy-page": {
diff --git a/web-app/messages/hr.json b/web-app/messages/hr.json
index 4fc3926..dde799a 100644
--- a/web-app/messages/hr.json
+++ b/web-app/messages/hr.json
@@ -479,6 +479,10 @@
"error": {
"title": "Odjava Nije Uspjela",
"unknown": "Došlo je do greške prilikom odjave. Molimo pokušajte ponovno ili kontaktirajte vašeg vlasnika nekretnine."
+ },
+ "not-allowed": {
+ "title": "Akcija Nije Dopuštena",
+ "message": "Možete se odjaviti samo s potvrđenih email adresa. Ova email adresa još nije potvrđena ili je već odjavljena."
}
},
"privacy-policy-page": {