diff --git a/src/components/EmailSection/EmailSection.vue b/src/components/EmailSection/EmailSection.vue
index 0495863..e756380 100644
--- a/src/components/EmailSection/EmailSection.vue
+++ b/src/components/EmailSection/EmailSection.vue
@@ -1,195 +1,202 @@
-
-
-
-
-
-
- {{ t('nmcsettings', 'Additional emails') }}
-
-
-
-
-
-
-
-
- {{ t('nmcsettings', 'Add additional email') }}
-
-
-
-
-
-
-
+
+
+
+
+
+
+ {{ t('nmcsettings', 'Additional emails') }}
+
+
+
+
+
+
+
+
+ {{ t('nmcsettings', 'Add additional email') }}
+
+
+
+
+
+
+
diff --git a/src/service/PersonalInfo/EmailService.js b/src/service/PersonalInfo/EmailService.js
index c758e51..82eb8a0 100644
--- a/src/service/PersonalInfo/EmailService.js
+++ b/src/service/PersonalInfo/EmailService.js
@@ -1,151 +1,153 @@
-import axios from '@nextcloud/axios'
-import { getCurrentUser } from '@nextcloud/auth'
-import { generateOcsUrl } from '@nextcloud/router'
-import { confirmPassword } from '@nextcloud/password-confirmation'
-import '@nextcloud/password-confirmation/dist/style.css'
-
-import { ACCOUNT_PROPERTY_ENUM, SCOPE_SUFFIX } from '../../constants/AccountPropertyConstants.js'
-
-/**
- * Save the primary email of the user
- *
- * @param {string} email the primary email
- * @return {object}
- */
-export const savePrimaryEmail = async (email) => {
- const userId = getCurrentUser().uid
- const url = generateOcsUrl('cloud/users/{userId}', { userId })
-
- await confirmPassword()
-
- const res = await axios.put(url, {
- key: ACCOUNT_PROPERTY_ENUM.EMAIL,
- value: email,
- })
-
- return res.data
-}
-
-/**
- * Save an additional email of the user
- *
- * Will be appended to the user's additional emails*
- *
- * @param {string} email the additional email
- * @return {object}
- */
-export const saveAdditionalEmail = async (email) => {
- const userId = getCurrentUser().uid
- const url = generateOcsUrl('cloud/users/{userId}', { userId })
-
- await confirmPassword()
-
- const res = await axios.put(url, {
- key: ACCOUNT_PROPERTY_ENUM.EMAIL_COLLECTION,
- value: email,
- })
-
- return res.data
-}
-
-/**
- * Save the notification email of the user
- *
- * @param {string} email the notification email
- * @return {object}
- */
-export const saveNotificationEmail = async (email) => {
- const userId = getCurrentUser().uid
- const url = generateOcsUrl('cloud/users/{userId}', { userId })
-
- await confirmPassword()
-
- const res = await axios.put(url, {
- key: ACCOUNT_PROPERTY_ENUM.NOTIFICATION_EMAIL,
- value: email,
- })
-
- return res.data
-}
-
-/**
- * Remove an additional email of the user
- *
- * @param {string} email the additional email
- * @return {object}
- */
-export const removeAdditionalEmail = async (email) => {
- const userId = getCurrentUser().uid
- const url = generateOcsUrl('cloud/users/{userId}/{collection}', { userId, collection: ACCOUNT_PROPERTY_ENUM.EMAIL_COLLECTION })
-
- await confirmPassword()
-
- const res = await axios.put(url, {
- key: email,
- value: '',
- })
-
- return res.data
-}
-
-/**
- * Update an additional email of the user
- *
- * @param {string} prevEmail the additional email to be updated
- * @param {string} newEmail the new additional email
- * @return {object}
- */
-export const updateAdditionalEmail = async (prevEmail, newEmail) => {
- const userId = getCurrentUser().uid
- const url = generateOcsUrl('cloud/users/{userId}/{collection}', { userId, collection: ACCOUNT_PROPERTY_ENUM.EMAIL_COLLECTION })
-
- await confirmPassword()
-
- const res = await axios.put(url, {
- key: prevEmail,
- value: newEmail,
- })
-
- return res.data
-}
-
-/**
- * Save the federation scope for the primary email of the user
- *
- * @param {string} scope the federation scope
- * @return {object}
- */
-export const savePrimaryEmailScope = async (scope) => {
- const userId = getCurrentUser().uid
- const url = generateOcsUrl('cloud/users/{userId}', { userId })
-
- await confirmPassword()
-
- const res = await axios.put(url, {
- key: `${ACCOUNT_PROPERTY_ENUM.EMAIL}${SCOPE_SUFFIX}`,
- value: scope,
- })
-
- return res.data
-}
-
-/**
- * Save the federation scope for the additional email of the user
- *
- * @param {string} email the additional email
- * @param {string} scope the federation scope
- * @return {object}
- */
-export const saveAdditionalEmailScope = async (email, scope) => {
- const userId = getCurrentUser().uid
- const url = generateOcsUrl('cloud/users/{userId}/{collectionScope}', { userId, collectionScope: `${ACCOUNT_PROPERTY_ENUM.EMAIL_COLLECTION}${SCOPE_SUFFIX}` })
-
- await confirmPassword()
-
- const res = await axios.put(url, {
- key: email,
- value: scope,
- })
-
- return res.data
-}
+import axios from '@nextcloud/axios'
+import { getCurrentUser } from '@nextcloud/auth'
+import { generateOcsUrl } from '@nextcloud/router'
+import { confirmPassword } from '@nextcloud/password-confirmation'
+import '@nextcloud/password-confirmation/dist/style.css'
+import { convertEmailDomainToASCII } from '../../utils/email.js'
+
+import { ACCOUNT_PROPERTY_ENUM, SCOPE_SUFFIX } from '../../constants/AccountPropertyConstants.js'
+
+/**
+ * Save the primary email of the user
+ *
+ * @param {string} email the primary email
+ * @return {object}
+ */
+export const savePrimaryEmail = async (email) => {
+ const userId = getCurrentUser().uid
+ const url = generateOcsUrl('cloud/users/{userId}', { userId })
+
+ await confirmPassword()
+
+ const res = await axios.put(url, {
+ key: ACCOUNT_PROPERTY_ENUM.EMAIL,
+ value: convertEmailDomainToASCII(email),
+ })
+
+ return res.data
+}
+
+/**
+ * Save an additional email of the user
+ *
+ * Will be appended to the user's additional emails*
+ *
+ * @param {string} email the additional email
+ * @return {object}
+ */
+export const saveAdditionalEmail = async (email) => {
+ const userId = getCurrentUser().uid
+ const url = generateOcsUrl('cloud/users/{userId}', { userId })
+
+ await confirmPassword()
+
+ const res = await axios.put(url, {
+ key: ACCOUNT_PROPERTY_ENUM.EMAIL_COLLECTION,
+ value: convertEmailDomainToASCII(email),
+ })
+
+ return res.data
+}
+
+/**
+ * Save the notification email of the user
+ *
+ * @param {string} email the notification email
+ * @return {object}
+ */
+export const saveNotificationEmail = async (email) => {
+ const userId = getCurrentUser().uid
+ const url = generateOcsUrl('cloud/users/{userId}', { userId })
+
+ await confirmPassword()
+
+ const res = await axios.put(url, {
+ key: ACCOUNT_PROPERTY_ENUM.NOTIFICATION_EMAIL,
+ value: convertEmailDomainToASCII(email),
+ })
+
+ return res.data
+}
+
+/**
+ * Remove an additional email of the user
+ *
+ * @param {string} email the additional email
+ * @return {object}
+ */
+export const removeAdditionalEmail = async (email) => {
+ const userId = getCurrentUser().uid
+ const url = generateOcsUrl('cloud/users/{userId}/{collection}', { userId, collection: ACCOUNT_PROPERTY_ENUM.EMAIL_COLLECTION })
+
+ await confirmPassword()
+
+ const res = await axios.put(url, {
+ key: convertEmailDomainToASCII(email),
+ value: '',
+ })
+
+ return res.data
+}
+
+/**
+ * Update an additional email of the user
+ *
+ * @param {string} prevEmail the additional email to be updated
+ * @param {string} newEmail the new additional email
+ * @return {object}
+ */
+export const updateAdditionalEmail = async (prevEmail, newEmail) => {
+ const userId = getCurrentUser().uid
+ const url = generateOcsUrl('cloud/users/{userId}/{collection}', { userId, collection: ACCOUNT_PROPERTY_ENUM.EMAIL_COLLECTION })
+
+ await confirmPassword()
+
+ const res = await axios.put(url, {
+ key: convertEmailDomainToASCII(prevEmail),
+ value: convertEmailDomainToASCII(newEmail),
+ })
+
+ return res.data
+
+}
+
+/**
+ * Save the federation scope for the primary email of the user
+ *
+ * @param {string} scope the federation scope
+ * @return {object}
+ */
+export const savePrimaryEmailScope = async (scope) => {
+ const userId = getCurrentUser().uid
+ const url = generateOcsUrl('cloud/users/{userId}', { userId })
+
+ await confirmPassword()
+
+ const res = await axios.put(url, {
+ key: `${ACCOUNT_PROPERTY_ENUM.EMAIL}${SCOPE_SUFFIX}`,
+ value: scope,
+ })
+
+ return res.data
+}
+
+/**
+ * Save the federation scope for the additional email of the user
+ *
+ * @param {string} email the additional email
+ * @param {string} scope the federation scope
+ * @return {object}
+ */
+export const saveAdditionalEmailScope = async (email, scope) => {
+ const userId = getCurrentUser().uid
+ const url = generateOcsUrl('cloud/users/{userId}/{collectionScope}', { userId, collectionScope: `${ACCOUNT_PROPERTY_ENUM.EMAIL_COLLECTION}${SCOPE_SUFFIX}` })
+
+ await confirmPassword()
+
+ const res = await axios.put(url, {
+ key: convertEmailDomainToASCII(email),
+ value: scope,
+ })
+
+ return res.data
+}
diff --git a/src/utils/email.js b/src/utils/email.js
new file mode 100644
index 0000000..a73f041
--- /dev/null
+++ b/src/utils/email.js
@@ -0,0 +1,55 @@
+import punycode from 'punycode'
+
+/**
+ * Convert the domain part of an email address to ASCII (punycode) if needed.
+ * Returns the original email if conversion fails or input is malformed.
+ *
+ * @param {string} email
+ * @return {string}
+ */
+export function convertEmailDomainToASCII(email) {
+ if (typeof email !== 'string') {
+ return email
+ }
+ const parts = email.split('@')
+ if (parts.length !== 2) {
+ return email
+ }
+ const [local, domain] = parts
+ if (/[^\x00-\x7F]/.test(domain)) {
+ try {
+ const ascii = punycode.toASCII(domain)
+ return `${local}@${ascii}`
+ } catch (e) {
+ return email
+ }
+ }
+ return email
+}
+
+/**
+ * Convert punycode domain back to Unicode for display purposes.
+ * If the domain is not punycoded, returns the original email.
+ *
+ * @param {string} email
+ * @return {string}
+ */
+export function convertEmailDomainToUnicode(email) {
+ if (typeof email !== 'string') {
+ return email
+ }
+ const parts = email.split('@')
+ if (parts.length !== 2) {
+ return email
+ }
+ const [local, domain] = parts
+ if (/\bxn--/i.test(domain)) {
+ try {
+ const unicode = punycode.toUnicode(domain)
+ return `${local}@${unicode}`
+ } catch (e) {
+ return email
+ }
+ }
+ return email
+}