Add IBAN validation using iban.js library
Implemented optional IBAN validation for the account form profile: - Installed iban.js package for robust IBAN validation - Added Zod validation with IBAN.isValid() for format checking - Normalizes IBAN (removes spaces, uppercase) before storage - Validates country-specific formats and checksums - Added validation error messages in English and Croatian 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -10,6 +10,7 @@ import { IntlTemplateFn } from '@/app/i18n';
|
||||
import { getTranslations, getLocale } from "next-intl/server";
|
||||
import { revalidatePath } from 'next/cache';
|
||||
import { gotoHomeWithMessage } from './navigationActions';
|
||||
import * as IBAN from 'iban';
|
||||
|
||||
export type State = {
|
||||
errors?: {
|
||||
@@ -29,7 +30,17 @@ const FormSchema = (t: IntlTemplateFn) => z.object({
|
||||
firstName: z.string().optional(),
|
||||
lastName: z.string().optional(),
|
||||
address: z.string().optional(),
|
||||
iban: z.string().optional(),
|
||||
iban: z.string()
|
||||
.optional()
|
||||
.refine(
|
||||
(val) => {
|
||||
if (!val || val.trim() === '') return true;
|
||||
// Remove spaces and validate using iban.js library
|
||||
const cleaned = val.replace(/\s/g, '').toUpperCase();
|
||||
return IBAN.isValid(cleaned);
|
||||
},
|
||||
{ message: t("iban-invalid") }
|
||||
),
|
||||
});
|
||||
|
||||
/**
|
||||
@@ -73,6 +84,9 @@ export const updateUserProfile = withUser(async (user: AuthenticatedUser, prevSt
|
||||
|
||||
const { firstName, lastName, address, iban } = validatedFields.data;
|
||||
|
||||
// Normalize IBAN: remove spaces and convert to uppercase
|
||||
const normalizedIban = iban ? iban.replace(/\s/g, '').toUpperCase() : null;
|
||||
|
||||
// Update the user profile in MongoDB
|
||||
const dbClient = await getDbClient();
|
||||
const { id: userId } = user;
|
||||
@@ -82,7 +96,7 @@ export const updateUserProfile = withUser(async (user: AuthenticatedUser, prevSt
|
||||
firstName: firstName || null,
|
||||
lastName: lastName || null,
|
||||
address: address || null,
|
||||
iban: iban || null,
|
||||
iban: normalizedIban,
|
||||
};
|
||||
|
||||
await dbClient.collection<UserProfile>("users")
|
||||
|
||||
@@ -149,6 +149,8 @@
|
||||
"iban-placeholder": "Enter your IBAN",
|
||||
"save-button": "Save",
|
||||
"cancel-button": "Cancel",
|
||||
"validation": {}
|
||||
"validation": {
|
||||
"iban-invalid": "Invalid IBAN format. Please enter a valid IBAN"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -148,6 +148,8 @@
|
||||
"iban-placeholder": "Unesite svoj IBAN",
|
||||
"save-button": "Spremi",
|
||||
"cancel-button": "Odbaci",
|
||||
"validation": {}
|
||||
"validation": {
|
||||
"iban-invalid": "Neispravan IBAN format. Molimo unesite ispravan IBAN."
|
||||
}
|
||||
}
|
||||
}
|
||||
14
package-lock.json
generated
14
package-lock.json
generated
@@ -13,6 +13,7 @@
|
||||
"@mui/icons-material": "^7.3.5",
|
||||
"@mui/material": "^7.3.5",
|
||||
"@tailwindcss/typography": "^0.5.10",
|
||||
"@types/iban": "^0.0.35",
|
||||
"@types/node": "20.5.7",
|
||||
"@zxing/browser": "^0.1.4",
|
||||
"@zxing/library": "^0.20.0",
|
||||
@@ -20,6 +21,7 @@
|
||||
"bcrypt": "^5.1.1",
|
||||
"clsx": "^2.0.0",
|
||||
"daisyui": "^4.5.0",
|
||||
"iban": "^0.0.14",
|
||||
"is-ua-webview": "^1.1.2",
|
||||
"mongodb": "^6.3.0",
|
||||
"next": "^14.0.2",
|
||||
@@ -1745,6 +1747,12 @@
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/iban": {
|
||||
"version": "0.0.35",
|
||||
"resolved": "https://registry.npmjs.org/@types/iban/-/iban-0.0.35.tgz",
|
||||
"integrity": "sha512-BOsp/b0ypIBnZdp1R8aP3n4w7I0n6vcObXtD0OT91lVSdo+Bx4VL26tW3yx1Dr9I4D5H3A27IOZoMVAdVfG4FQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/json-schema": {
|
||||
"version": "7.0.15",
|
||||
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
|
||||
@@ -5013,6 +5021,12 @@
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/iban": {
|
||||
"version": "0.0.14",
|
||||
"resolved": "https://registry.npmjs.org/iban/-/iban-0.0.14.tgz",
|
||||
"integrity": "sha512-+rocNKk+Ga9m8Lr9fTMWd+87JnsBrucm0ZsIx5ROOarZlaDLmd+FKdbtvb0XyoBw9GAFOYG2GuLqoNB16d+p3w==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/ignore": {
|
||||
"version": "5.3.1",
|
||||
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz",
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
"@mui/icons-material": "^7.3.5",
|
||||
"@mui/material": "^7.3.5",
|
||||
"@tailwindcss/typography": "^0.5.10",
|
||||
"@types/iban": "^0.0.35",
|
||||
"@types/node": "20.5.7",
|
||||
"@zxing/browser": "^0.1.4",
|
||||
"@zxing/library": "^0.20.0",
|
||||
@@ -22,6 +23,7 @@
|
||||
"bcrypt": "^5.1.1",
|
||||
"clsx": "^2.0.0",
|
||||
"daisyui": "^4.5.0",
|
||||
"iban": "^0.0.14",
|
||||
"is-ua-webview": "^1.1.2",
|
||||
"mongodb": "^6.3.0",
|
||||
"next": "^14.0.2",
|
||||
|
||||
Reference in New Issue
Block a user