diff --git a/api-gateway/src/app.controller.ts b/api-gateway/src/app.controller.ts index e8c51c72..d9b740b9 100644 --- a/api-gateway/src/app.controller.ts +++ b/api-gateway/src/app.controller.ts @@ -314,7 +314,19 @@ export class AppController { number_house, ); } - + + @Put('user/changePassword/:id') + changePassword( + @Param('id') id: string, + @Body('password') password: string, + ) { + + return this.appService.changePassword( + id, + password, + ); + } + // #==== API Communities @Post('community/createCommunity') createCommunity( diff --git a/api-gateway/src/app.service.ts b/api-gateway/src/app.service.ts index 0213a277..235090ec 100644 --- a/api-gateway/src/app.service.ts +++ b/api-gateway/src/app.service.ts @@ -387,6 +387,16 @@ export class AppService { } + changePassword(id: string, password: string) { + const pattern = { cmd: 'changePassword' }; + const payload = { id: id, password: password }; + return this.clientUserApp + .send(pattern, payload) + .pipe(map((message: string) => ({ message }))); + } + + + // ====================== COMMUNITIES =============================== changeStatusCommunity(pId: string, pStatus: string) { const pattern = { cmd: 'changeStatus' }; diff --git a/servicio-usuarios/src/schemas/user.schema.ts b/servicio-usuarios/src/schemas/user.schema.ts index f09a3231..38c97157 100644 --- a/servicio-usuarios/src/schemas/user.schema.ts +++ b/servicio-usuarios/src/schemas/user.schema.ts @@ -7,20 +7,20 @@ export type UserDocument = User & Document; @Schema({ collection: 'users'}) export class User { - @Prop({index: true}) - dni!: string; + @Prop() + dni: string; - @Prop({required: true}) + @Prop() name: string; - @Prop({required: true}) + @Prop() last_name: string; - @Prop({required: true, unique: true}) + @Prop() email: string; - @Prop({required: true, unique: true}) - phone: number; + @Prop() + phone: string; @Prop() password: string; diff --git a/servicio-usuarios/src/users/users.controller.ts b/servicio-usuarios/src/users/users.controller.ts index 314f192b..0bf8f960 100644 --- a/servicio-usuarios/src/users/users.controller.ts +++ b/servicio-usuarios/src/users/users.controller.ts @@ -72,8 +72,6 @@ export class UsersController { @MessagePattern({ cmd: 'updateUser' }) update(@Payload() user: UserDocument) { - console.log(user); - return this.userService.update(user['id'], user); } @@ -167,4 +165,13 @@ export class UsersController { let pstatus = body['status']; return this.userService.changeStatus(pid, pstatus); } + + @MessagePattern({ cmd: 'changePassword' }) + changePassword(@Payload() body: string) { + let pid = body['id']; + let password = body['password']; + return this.userService.changePassword(pid, password); + } + + } diff --git a/servicio-usuarios/src/users/users.service.ts b/servicio-usuarios/src/users/users.service.ts index e1840769..0e5a3dff 100644 --- a/servicio-usuarios/src/users/users.service.ts +++ b/servicio-usuarios/src/users/users.service.ts @@ -117,9 +117,6 @@ export class UsersService { } async update(id: string, user: UserDocument) { - console.log(id) - console.log(user) - return this.userModel.findOneAndUpdate({ _id: id }, { name: user['name'], last_name: user['last_name'], dni: user['dni'], email: user['email'], phone: user['phone'] @@ -182,7 +179,6 @@ export class UsersService { } }); }); - return userReturn; } @@ -200,19 +196,14 @@ export class UsersService { return this.userModel.find({ user_type: 2 }).exec(); } - //find inquilinos async findTenants(): Promise { return this.userModel.find({ user_type: 3 }).exec(); } - //find inquilinos async findTenantsCommunity(pcommunity_id: string) { //let tenants = await this.findCommunityTenants(pcommunity_id); - - - return await this.userModel.find({ community_id: pcommunity_id, user_type: 4 }) } @@ -338,5 +329,14 @@ export class UsersService { await this.userModel.updateMany({community_id: community_id, user_type:'3' }, {"$set":{"community_id": '', "status": '-1'} }); return this.userModel.updateMany({ community_id: community_id, user_type: '4' }, { "$set": { "community_id": '', "status": '-1' } }); } + + + async changePassword(id: string, password: string) { + return this.userModel.findOneAndUpdate({ _id: id }, { password: password }, { + new: true, + }); + } + + } diff --git a/web-ui/web-react/package-lock.json b/web-ui/web-react/package-lock.json index 6699ac1c..423a1ef0 100644 --- a/web-ui/web-react/package-lock.json +++ b/web-ui/web-react/package-lock.json @@ -22,6 +22,7 @@ "chart.js": "3.3.2", "classnames": "^2.2.6", "cors": "^2.8.5", + "md5": "^2.3.0", "primeflex": "3.1.0", "primeicons": "^5.0.0", "primereact": "7.2.0", @@ -4677,6 +4678,14 @@ "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==" }, + "node_modules/charenc": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", + "integrity": "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==", + "engines": { + "node": "*" + } + }, "node_modules/chart.js": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-3.3.2.tgz", @@ -5384,6 +5393,14 @@ "semver": "bin/semver" } }, + "node_modules/crypt": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", + "integrity": "sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==", + "engines": { + "node": "*" + } + }, "node_modules/crypto-browserify": { "version": "3.12.0", "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", @@ -10589,6 +10606,16 @@ "node": ">=0.10.0" } }, + "node_modules/md5": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz", + "integrity": "sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==", + "dependencies": { + "charenc": "0.0.2", + "crypt": "0.0.2", + "is-buffer": "~1.1.6" + } + }, "node_modules/md5.js": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", @@ -21618,6 +21645,11 @@ "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==" }, + "charenc": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", + "integrity": "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==" + }, "chart.js": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-3.3.2.tgz", @@ -22179,6 +22211,11 @@ } } }, + "crypt": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", + "integrity": "sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==" + }, "crypto-browserify": { "version": "3.12.0", "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", @@ -26217,6 +26254,16 @@ "object-visit": "^1.0.0" } }, + "md5": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz", + "integrity": "sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==", + "requires": { + "charenc": "0.0.2", + "crypt": "0.0.2", + "is-buffer": "~1.1.6" + } + }, "md5.js": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", diff --git a/web-ui/web-react/package.json b/web-ui/web-react/package.json index 4cb7843c..cc71cde5 100644 --- a/web-ui/web-react/package.json +++ b/web-ui/web-react/package.json @@ -22,6 +22,7 @@ "chart.js": "3.3.2", "classnames": "^2.2.6", "cors": "^2.8.5", + "md5": "^2.3.0", "primeflex": "3.1.0", "primeicons": "^5.0.0", "primereact": "7.2.0", diff --git a/web-ui/web-react/src/components/PerfilAdminComunidad.js b/web-ui/web-react/src/components/PerfilAdminComunidad.js index 438c4312..cc73e17f 100644 --- a/web-ui/web-react/src/components/PerfilAdminComunidad.js +++ b/web-ui/web-react/src/components/PerfilAdminComunidad.js @@ -8,6 +8,13 @@ import { faMapLocationDot } from '@fortawesome/free-solid-svg-icons'; import { faPhoneAlt } from '@fortawesome/free-solid-svg-icons'; import { faHashtag } from '@fortawesome/free-solid-svg-icons'; import { faCircleQuestion } from '@fortawesome/free-solid-svg-icons'; +import { Button } from 'primereact/button'; +import { Toast } from 'primereact/toast'; +import { Dialog } from 'primereact/dialog'; +import { Toolbar } from 'primereact/toolbar'; +import { InputText } from 'primereact/inputtext'; +import classNames from 'classnames'; +import md5 from 'md5'; const PerfilAdminComunidad = () => { @@ -42,6 +49,13 @@ const PerfilAdminComunidad = () => { houses: [], }; + let emptyNewPassword = { + _id: null, + passwordOld: '', + passwordNew: '', + passwordConfirm: '' + } + const [admin, setAdmin] = useState(emptyAdminCommunity); const [community, setCommunity] = useState(emptyCommunity); const [cookies, setCookie] = useCookies(); @@ -52,34 +66,36 @@ const PerfilAdminComunidad = () => { const [provincesList, setProvincesList] = useState([]); const [cantonsList, setCantonsList] = useState([]); const [districtsList, setDistrictsList] = useState([]); + const [editAdminDialog, setEditAdminDialog] = useState(false); + const [editPasswordDialog, setEditPasswordDialog] = useState(false); + const [submitted, setSubmitted] = useState(false); + const toast = useRef(null); + const [newPassword, setNewPassword] = useState(emptyNewPassword); + + async function getProvinces() { const response = await fetch('assets/demo/data/provincias.json', { - method: 'GET', + method: 'GET', }); return await response.json(); - } - - - async function getCantons() { - const response = await fetch('assets/demo/data/cantones.json', { - method: 'GET', - }); - return await response.json(); - } - - - async function getDistricts() { - const response = await fetch('assets/demo/data/distritos.json', { - method: 'GET', - }); - return await response.json(); - } - - - + } + + + async function getCantons() { + const response = await fetch('assets/demo/data/cantones.json', { + method: 'GET', + }); + return await response.json(); + } + + async function getDistricts() { + const response = await fetch('assets/demo/data/distritos.json', { + method: 'GET', + }); + return await response.json(); + } - async function getAdmin() { await fetch('http://localhost:4000/user/findUserById/' + cookies.id, { method: 'GET' }) .then((response) => response.json()) @@ -100,6 +116,7 @@ const PerfilAdminComunidad = () => { getAdmin(); }, []) + async function getCommunity() { let pList = await getProvinces(); let cList = await getCantons(); @@ -135,8 +152,107 @@ const PerfilAdminComunidad = () => { tenantsList(cookies.community_id); }, []) + const saveAdmin = () => { + let _admin = { ...admin }; + _admin.community_id = cookies.community_id; + + if (_admin.name && _admin.dni && + _admin.last_name && _admin.email && + _admin.phone) { + + console.log(`Actualizando admnistrador de comunidad: ${_admin}`) + _admin.community_id = cookies.community_id; + console.log(`Actualizando admnistrador de comunidad: ${_admin}`) + + fetch(`http://localhost:4000/user/updateAdminCommunity/${_admin._id}`, { + cache: 'no-cache', + method: 'PUT', + body: JSON.stringify(_admin), + headers: { + 'Content-Type': 'application/json', + }, + }).then((response) => { + if (response.status !== 200) + console.log(`Hubo un error en el servicio: ${response.status}`) + else return response.json() + }).then((response) => { + + toast.current.show({ + severity: 'success', + summary: 'Éxito', + detail: 'Administrador de comunidad actualizado', + life: 3000, + }) + + setAdmin(response.message); + setEditAdminDialog(false); + + }) + + + } else { + setSubmitted(true); + } + + + } + + const savePassword = () => { + let _admin = { ...admin }; + let _newPassword = { ...newPassword }; + + if (_newPassword.passwordOld && _newPassword.passwordNew && + _newPassword.passwordNew === _newPassword.passwordConfirm) { + + _admin.password = md5(_newPassword.passwordNew); + console.log(`Actualizando admnistrador de comunidad: ${_admin}`) + + fetch(`http://localhost:4000/user/changePassword/${_admin._id}`, { + cache: 'no-cache', + method: 'PUT', + body: JSON.stringify(_admin), + headers: { + 'Content-Type': 'application/json', + }, + }).then((response) => { + if (response.status !== 200) + console.log(`Hubo un error en el servicio: ${response.status}`) + else return response.json() + }).then((response) => { + + toast.current.show({ + severity: 'success', + summary: 'Éxito', + detail: 'Administrador de comunidad actualizado', + life: 3000, + }) + setAdmin(_admin); + setEditPasswordDialog(false); + }) + + + } else { + setSubmitted(true); + } + + + } + + const findRepeated = async (name, value) => { + let _administrators; + await fetch('http://localhost:4000/user/findAdminComunidad/', { method: 'GET' }) + .then((response) => response.json()) + .then((data) => data.message) + .then(data => { + data = data.filter( + (val) => val.status != -1, + ); + _administrators = data; + }); + let value_filtered = await _administrators.filter(item => item[`${name}`] === value); + return value_filtered.length; + } - function findNameTenant(tenant_id) { let name = ''; if (tenant_id == '') { @@ -148,6 +264,105 @@ const PerfilAdminComunidad = () => { return name; } + const onInputChange = (e, name) => { + const val = (e.target && e.target.value) || ''; + let _admin = { ...admin }; + _admin[`${name}`] = val; + setAdmin(_admin); + } + + + const onInputChangePassword = (e, name) => { + const val = (e.target && e.target.value) || ''; + let _pass = { ...newPassword }; + _pass[`${name}`] = val; + setNewPassword(_pass); + } + + + const editAdmin = (admin) => { + setAdmin(admin); + setEditAdminDialog(true); + } + + const editPassword = () => { + setNewPassword(emptyNewPassword); + setEditPasswordDialog(true); + } + + const hideEditAdminDialog = () => { + setSubmitted(false); + setEditAdminDialog(false); + } + + const hideEditPasswordDialog = () => { + setSubmitted(false); + setEditPasswordDialog(false); + } + + const actionsAdminCommunity = (rowData) => { + return ( + <> +
+
+
+
+
+
+
+
+ + ) + } + + + const editAdminDialogFooter = ( + <> +