System Information
- Strapi Version: 3.6.2
- Operating System: windows 10
- Database: sqlite
- Node Version: 14
- NPM Version: 6.14.14
- Yarn Version:
Hello,
I’m struggling for creating a custom for let user update their username, email and password.
So far I’m stuck with a 403 forbidden for my route.
user.js:98 PUT http://localhost:8082/users/updateMe 403 (Forbidden)
changepassword @ user.js:98
user.js:108 {statusCode: 403, error: 'Forbidden', message: 'Forbidden'}
Here my custom route \api\userupdate\config\routes.json"
{
"method": "PUT",
"path": "/users/updateMe",
"handler": "users.updateMe",
"config": {
"policies": [],
"prefix": "",
"description": "Update the logged in user information",
"tag": {
"plugin": "users-permissions",
"name": "User",
"actionType": "update"
}
}
}
And my controller “\api\userupdate\controllers\users.js”
'use strict';
/**
* api/userupdate/controllers/users.js
*/
const _ = require('lodash');
const { sanitizeEntity } = require('strapi-utils');
const sanitizeUser = user =>
sanitizeEntity(user, {
model: strapi.query('user', 'users-permissions').model,
});
module.exports = { /**
* Update authenticated user.
* @return {Object|Array}
*/
async updateMe(ctx) {
const advancedConfigs = await strapi
.store({
environment: '',
type: 'plugin',
name: 'users-permissions',
key: 'advanced',
})
.get();
const user = ctx.state.user;
const { id, email, username, password } = user;
if (!user) {
return ctx.badRequest(null, [{ messages: [{ id: 'No authorization header was found' }] }]);
}
if (_.has(ctx.request.body, 'email') && !email) {
return ctx.badRequest('email.notNull');
}
if (_.has(ctx.request.body, 'username') && !username) {
return ctx.badRequest('username.notNull');
}
if (_.has(ctx.request.body, 'password') && !password && user.provider === 'local') {
return ctx.badRequest('password.notNull');
}
if (_.has(ctx.request.body, 'role')) {
return ctx.badRequest(null, [{ messages: [{ id: 'Cannot update own role' }] }]);
}
if (_.has(ctx.request.body, 'confirmed')) {
return ctx.badRequest(null, [{ messages: [{ id: 'Cannot change own confirmed status' }] }]);
}
if (_.has(ctx.request.body, 'provider')) {
return ctx.badRequest(null, [{ messages: [{ id: 'Cannot change own provider' }] }]);
}
if (_.has(ctx.request.body, 'resetPasswordToken')) {
return ctx.badRequest(null, [{ messages: [{ id: 'Cannot set own password reset token' }] }]);
}
if (_.has(ctx.request.body, 'blocked')) {
return ctx.badRequest(null, [{ messages: [{ id: 'Cannot change own blocked status' }] }]);
}
if (_.has(ctx.request.body, 'username')) {
const userWithSameUsername = await strapi
.query('user', 'users-permissions')
.findOne({ username });
if (userWithSameUsername && userWithSameUsername.id != id) {
return ctx.badRequest(
null,
formatError({
id: 'Auth.form.error.username.taken',
message: 'username.alreadyTaken.',
field: ['username'],
})
);
}
}
if (_.has(ctx.request.body, 'email') && advancedConfigs.unique_email) {
const userWithSameEmail = await strapi.query('user', 'users-permissions').findOne({ email });
if (userWithSameEmail && userWithSameEmail.id != id) {
return ctx.badRequest(
null,
formatError({
id: 'Auth.form.error.email.taken',
message: 'Email already taken',
field: ['email'],
})
);
}
}
let updateData = {
...ctx.request.body,
};
if (_.has(ctx.request.body, 'password') && password === user.password) {
delete updateData.password;
}
const data = await strapi.plugins['users-permissions'].services.user.edit({ id }, updateData);
const newData = sanitizeUser(data);
ctx.send(newData);
},
}
I’ve done many many test to try making a custom udpateMe feature for logged user.
This code is not from me, I’ve was unable to create one myself after many attempts.
In the backend , Role>Authenticated>permissions updateme is enable
also here my code in the frontend :
const url = "http://localhost:8082";
//partie changepassword
const useroptionsForm = document.forms.useroptions;
useroptionsForm.addEventListener('submit',changepassword);
init()
function init() {
const resultat = retrieveJWTtoken();
//console.log(resultat);
if (resultat.status === "anonymous") {
window.location.href = './index.html';
};
afficheProfile();
}
function deconnexion() {
localStorage.removeItem("user");
init();
}
function retrieveJWTtoken() {
//const userFromLocalStorage = localStorage.getItem("user");
const userFromLocalStorage = getWithExpiry("user");
if (userFromLocalStorage) { //si user existe dans le storage local
const user = JSON.parse(userFromLocalStorage);
if (user.jwt != null) { //et que le jeton existe aussi
return {status: "authenticated",msg: "connexion réussie", token: user.jwt};
};
};
return { status: "anonymous",msg: "merci de vous connecter", token: null};
}
/*{id: 1, username: 'user', email: 'user@user.fr', provider: 'local', confirmed: true, …}
blocked: null
confirmed: false
created_at: "2021-09-02T15:51:22.903Z"
email: "user@user.fr"
id: 1
*/
function afficheProfile() {
//const token = JSON.parse(localStorage.getItem("user")).jwt; //voir fonction connexion
const getuser = getWithExpiry("user");
const token = JSON.parse(getuser).jwt; //voir fonction connexion
fetch(`${url}/users/me`,{
headers: {
"Authorization": `Bearer ${token}`,
},
})
.then((response) => response.json())
.then(data => {
console.log(data);
const usertext = document.getElementById("usertext");
if (usertext) {
usertext.textContent=data.username;
};
//console.log(isAdmin);
})
}
function getWithExpiry(key) {
const itemStr = localStorage.getItem(key)
// if the item doesn't exist, return null
if (!itemStr) {
return null
}
const item = JSON.parse(itemStr)
const now = new Date()
// compare the expiry time of the item with the current time
if (now.getTime() > item.expiry) {
// If the item is expired, delete the item from storage
// and return null
localStorage.removeItem(key)
return null
}
return item.value
}
function changepassword(eventregister) {
eventregister.preventDefault();
const getuser = getWithExpiry("user");
const token = JSON.parse(getuser).jwt; //voir fonction connexion
const username = useroptionsForm.username.value;
const email = useroptionsForm.email.value;
const password = useroptionsForm.password.value;
console.log(username,email,password);
//http://localhost:8082/users/updateMe
const payload = { //on envoie ces infos
username,
email,
password
};
fetch(`${url}/users/updateMe`,{
method: 'PUT',
headers: {
"Authorization": `Bearer ${token}`,
"Content-Type": "application/json"
},
body: JSON.stringify(payload)
})
.then((response) => response.json())
.then((data) => {
console.log(data);//retourne le nouverau jeton JWT
})
.catch(err => {
console.error(err);
})
}
Why I get this 403 error ? Can you help me please ?