From de6e55075bc940ad4b576ba1874ad58960dba11c Mon Sep 17 00:00:00 2001 From: Christopher Ng Date: Tue, 29 Jun 2021 18:45:35 +0000 Subject: Create personal info service Signed-off-by: Christopher Ng --- .../src/constants/AccountPropertyConstants.js | 83 +++++++++++ apps/settings/src/service/PersonalInfoService.js | 153 +++++++++++++++++++++ 2 files changed, 236 insertions(+) create mode 100644 apps/settings/src/constants/AccountPropertyConstants.js create mode 100644 apps/settings/src/service/PersonalInfoService.js diff --git a/apps/settings/src/constants/AccountPropertyConstants.js b/apps/settings/src/constants/AccountPropertyConstants.js new file mode 100644 index 00000000000..61e45be9b22 --- /dev/null +++ b/apps/settings/src/constants/AccountPropertyConstants.js @@ -0,0 +1,83 @@ +/** + * @copyright 2021, Christopher Ng + * + * @author Christopher Ng + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +/* + * SYNC to be kept in sync with lib/public/Accounts/IAccountManager.php + */ + +/** Enum of account properties */ +export const ACCOUNT_PROPERTY_ENUM = Object.freeze({ + AVATAR: 'avatar', + DISPLAYNAME: 'displayname', + PHONE: 'phone', + EMAIL: 'email', + WEBSITE: 'website', + ADDRESS: 'address', + TWITTER: 'twitter', + EMAIL_COLLECTION: 'additional_mail', +}) + +/** Enum of scopes */ +export const SCOPE_ENUM = Object.freeze({ + PRIVATE: 'v2-private', + LOCAL: 'v2-local', + FEDERATED: 'v2-federated', + PUBLISHED: 'v2-published', +}) + +/** Scope suffix */ +export const SCOPE_SUFFIX = 'Scope' + +/** Default additional email scope */ +export const DEFAULT_ADDITIONAL_EMAIL_SCOPE = SCOPE_ENUM.LOCAL + +/** + * Enum of scope names to properties + * + * *Used for federation control* + */ +export const SCOPE_PROPERTY_ENUM = Object.freeze({ + [SCOPE_ENUM.PRIVATE]: { + name: SCOPE_ENUM.PRIVATE, + displayName: t('settings', 'Private'), + tooltip: t('settings', 'Only visible to people matched via phone number integration through Talk on mobile'), + iconClass: 'icon-phone', + }, + [SCOPE_ENUM.LOCAL]: { + name: SCOPE_ENUM.LOCAL, + displayName: t('settings', 'Local'), + tooltip: t('settings', 'Only visible to people on this instance and guests'), + iconClass: 'icon-password', + }, + [SCOPE_ENUM.FEDERATED]: { + name: SCOPE_ENUM.FEDERATED, + displayName: t('settings', 'Federated'), + tooltip: t('settings', 'Only synchronize to trusted servers'), + iconClass: 'icon-contacts-dark', + }, + [SCOPE_ENUM.PUBLISHED]: { + name: SCOPE_ENUM.PUBLISHED, + displayName: t('settings', 'Published'), + tooltip: t('settings', 'Synchronize to trusted servers and the global and public address book'), + iconClass: 'icon-link', + }, +}) diff --git a/apps/settings/src/service/PersonalInfoService.js b/apps/settings/src/service/PersonalInfoService.js new file mode 100644 index 00000000000..d033666817f --- /dev/null +++ b/apps/settings/src/service/PersonalInfoService.js @@ -0,0 +1,153 @@ +/** + * @copyright 2021, Christopher Ng + * + * @author Christopher Ng + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +import axios from '@nextcloud/axios' +import { getCurrentUser } from '@nextcloud/auth' +import { generateOcsUrl } from '@nextcloud/router' +import confirmPassword from '@nextcloud/password-confirmation' + +import { ACCOUNT_PROPERTY_ENUM, SCOPE_SUFFIX } from '../constants/AccountPropertyConstants' + +/** + * Save the primary email of the user + * + * @param {string} email the primary email + * @returns {Object} + */ +export const savePrimaryEmail = async(email) => { + const userId = getCurrentUser().uid + // TODO upgrade @nextcloud/router to v2.0 so we can remove the .slice() trailing slash hacks (same below) + const url = generateOcsUrl(`cloud/users/${userId}`, 2).slice(0, -1) + + 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 + * @returns {Object} + */ +export const saveAdditionalEmail = async(email) => { + const userId = getCurrentUser().uid + const url = generateOcsUrl(`cloud/users/${userId}`, 2).slice(0, -1) + + await confirmPassword() + + const res = await axios.put(url, { + key: ACCOUNT_PROPERTY_ENUM.EMAIL_COLLECTION, + value: email, + }) + + return res.data +} + +/** + * Remove an additional email of the user + * + * @param {string} email the additional email + * @returns {Object} + */ +export const removeAdditionalEmail = async(email) => { + const userId = getCurrentUser().uid + const url = generateOcsUrl(`cloud/users/${userId}/${ACCOUNT_PROPERTY_ENUM.EMAIL_COLLECTION}`, 2).slice(0, -1) + + 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 + * @returns {Object} + */ +export const updateAdditionalEmail = async(prevEmail, newEmail) => { + const userId = getCurrentUser().uid + const url = generateOcsUrl(`cloud/users/${userId}/${ACCOUNT_PROPERTY_ENUM.EMAIL_COLLECTION}`, 2).slice(0, -1) + + 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 + * @returns {Object} + */ +export const savePrimaryEmailScope = async(scope) => { + const userId = getCurrentUser().uid + const url = generateOcsUrl(`cloud/users/${userId}`, 2).slice(0, -1) + + 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 + * @returns {Object} + */ +export const saveAdditionalEmailScope = async(email, scope) => { + const userId = getCurrentUser().uid + const url = generateOcsUrl(`cloud/users/${userId}/${ACCOUNT_PROPERTY_ENUM.EMAIL_COLLECTION}${SCOPE_SUFFIX}`, 2).slice(0, -1) + + await confirmPassword() + + const res = await axios.put(url, { + key: email, + value: scope, + }) + + return res.data +} -- cgit v1.2.3