policies rewritten

parent 8367f4c3
...@@ -58,7 +58,6 @@ module.exports = { ...@@ -58,7 +58,6 @@ module.exports = {
* - 400 (Bad request) with error message "Missing parameters" * - 400 (Bad request) with error message "Missing parameters"
* - 401 (Unauthorized) with error message "Invalid email/password" * - 401 (Unauthorized) with error message "Invalid email/password"
* - 404 (Not found) with error message "Supervisor not found" * - 404 (Not found) with error message "Supervisor not found"
* - 401 (Unauthorized) with error message "Supervisor without students"
* - 500 (Server error) with error message "Error when connecting to database" * - 500 (Server error) with error message "Error when connecting to database"
*/ */
login: function (req, res) { login: function (req, res) {
...@@ -83,35 +82,12 @@ module.exports = { ...@@ -83,35 +82,12 @@ module.exports = {
}).then(function (supervisor) { }).then(function (supervisor) {
var stuSup = StuSup.findOne({id_sup: supervisor.id})
.then(function (stuSup) {
return stuSup;
});
var office = Office.findOne({id: supervisor.office})
.then(function (office) {
return office;
});
return [office, stuSup, supervisor];
}).spread(function(office, stuSup, supervisor) {
if (office) {
supervisor.office = office;
supervisor.isSupAdmin = (office.admin === supervisor.id);
}
if (!supervisor.isSupAdmin && !stuSup)
throw new Error("Supervisor without students");
supervisor.isSup = true;
return res.ok({ return res.ok({
user: supervisor, user: supervisor,
server_time: (new Date()).getTime(), server_time: (new Date()).getTime(),
token: sailsTokenAuth.issueToken(supervisor, sails.config.jwt.expiresInMinutes) token: sailsTokenAuth.issueToken(supervisor, sails.config.jwt.expiresInMinutes)
}); });
}) })
.catch(function (err) { .catch(function (err) {
return res.badRequest(err.message); return res.badRequest(err.message);
...@@ -155,31 +131,6 @@ module.exports = { ...@@ -155,31 +131,6 @@ module.exports = {
delete supervisor.password; delete supervisor.password;
supervisor.save(); supervisor.save();
// an email has to be sent to office administrators
if (token.role == 'tutor_office' || token.role === 'therapist_office') {
Office.findOne(token.id_off)
.populate('admin')
.then((off) => {
if (!off)
throw new Error("Office not found: ");
var message = sails.__({
phrase: token.role + '_request',
locale: supervisor.lang
}, {name: supervisor.name + " " + supervisor.surname, email: supervisor.email});
mailService.mailer()
.send({
to: off.admin.email,
text: message
})
.then(() => {})
.catch((err) => {throw err});
})
.catch((err) => {throw err;});
}
// welcome message is returned // welcome message is returned
return res.view('accountActivated', { return res.view('accountActivated', {
welcome_msg1: sails.__({ welcome_msg1: sails.__({
...@@ -265,41 +216,31 @@ module.exports = { ...@@ -265,41 +216,31 @@ module.exports = {
* the new account. * the new account.
* @param {request} req * @param {request} req
* { * {
* "name": "John"
* "surname": "Doe"
* "gender": "F/M"
* "password": "1234"
* "email": "john@doe.com" * "email": "john@doe.com"
* "address": "Nice street" (optional) * "password": "2nsodncoiaw3r4"
* "country": "ES/UK/..." (optional) * "lang": "es-es"
* "phone": "+123456789" (optional) * "role": "tutor"
* "lang": "ES/EN/..." (optional)
* "ttsEngine: "IVONA Text-to-Speech HQ" (optional)
* } * }
* @param {response} res * @param {response} res
* { * {
* "user": { * "user": {
* "id": 123 * "id": 123
* "name": "John" * "email": "john@doe.com"
* "gender": "M" * "role": "tutor"
* ... (same information specified in the request, without password) * "lang": "es-es"
* }, * },
* "token": "...as892..." * "token": "...as892..."
* } * }
*/ */
create: function (req, res) { create: function (req, res) {
var params = req.params.all(); var params = req.params.all();
var supervisor;
// Send email confirmation // Send email confirmation --------------------------------
function sendConfirmationMail(cb) { function sendConfirmationMail(supervisor, cb) {
console.log("mail------------\n" + JSON.stringify(supervisor));
var token = sailsTokenAuth.issueToken({ var token = sailsTokenAuth.issueToken({
id_sup: supervisor.id, id_sup: supervisor.id,
role: params.role, role: params.role,
id_off: params.id_off,
}, 60*24*7); // expires in 1 week }, 60*24*7); // expires in 1 week
var message = sails.__({ var message = sails.__({
...@@ -317,70 +258,30 @@ module.exports = { ...@@ -317,70 +258,30 @@ module.exports = {
}) })
.then(() => {cb();}) .then(() => {cb();})
.catch((err) => {cb(err);}); .catch((err) => {cb(err);});
} // /sendConfirmationEmail() } // ------------------------------ /sendConfirmationEmail()
sails.log.debug("Creating supervisor with params " + JSON.stringify(params)); sails.log.debug("Creating supervisor with params " + JSON.stringify(params));
if (!params.name || !params.surname || !params.gender || !params.password || !params.email ) if (!params.password || !params.email )
return res.badRequest("Invalid params"); return res.badRequest("Invalid params");
var supData = { var supData = {
name: params.name,
surname: params.surname,
gender: params.gender,
password: params.password, password: params.password,
email: params.email, email: params.email,
pic: sails.config.pictogram.paths.defaultAvatarFileName, pic: sails.config.pictogram.paths.defaultAvatarFileName,
address: params.address || '',
postal_code: params.postalCode || '',
country: params.country || '',
phone: params.phone || '',
lang: params.lang || 'es-es', lang: params.lang || 'es-es',
}; };
if (params.id_off && params.role == 'therapist_office')
supData.id_off = params.id_off;
console.log(JSON.stringify(supData));
Supervisor.create(supData) Supervisor.create(supData)
.then(function (sup) { .then(function (sup) {
if (!sup) if (!sup)
return res.serverError("Supervisor created but returned null"); return res.serverError("Supervisor created but returned null");
supervisor = sup; sendConfirmationMail(sup, (err) => {
if (err) throw err;
if (params.role === 'therapist_office' || params.role === 'tutor_office') { return res.ok();
sendConfirmationMail((err) => { });
if (err) throw err;
return res.ok();
});
} else if (params.role === 'therapist_nooffice' || params.role === 'tutor_nooffice') {
Office.create(params.office)
.then((off) => {
// link supervisor with office
console.log("supervisor: \n" + JSON.stringify(sup));
sup.id_off = off.id;
delete sup.password;
sup.save();
console.log("supervisor: \n" + JSON.stringify(sup));
// set supervisor as admin in the office
off.admin = sup.id;
off.save();
supervisor = sup;
sendConfirmationMail((err) => {
if (err) return res.serverError("Confirmation mail could not be sent: " + err);
return res.ok();
});
})
.catch((err) => {
return res.serverError("Supervisor could not be created: " + err);
});
} else
return res.badRequest("Invalid role");
}).catch(function (err) { }).catch(function (err) {
return res.serverError("Supervisor could not be created: " + err); return res.serverError("Supervisor could not be created: " + err);
}); });
...@@ -496,7 +397,6 @@ module.exports = { ...@@ -496,7 +397,6 @@ module.exports = {
supervisor.phone = req.body.phone || supervisor.phone; supervisor.phone = req.body.phone || supervisor.phone;
supervisor.lang = req.body.lang || supervisor.lang; supervisor.lang = req.body.lang || supervisor.lang;
supervisor.ttsEngine = req.body.ttsEngine || supervisor.ttsEngine; supervisor.ttsEngine = req.body.ttsEngine || supervisor.ttsEngine;
supervisor.office = req.body.office || supervisor.office;
supervisor.save(function (error) { supervisor.save(function (error) {
if (error) throw error; if (error) throw error;
return res.ok(supervisor); return res.ok(supervisor);
......
...@@ -78,16 +78,6 @@ module.exports = { ...@@ -78,16 +78,6 @@ module.exports = {
type: "string", type: "string",
size: 10 size: 10
}, },
// Relación con Teacher. [1 Office to N Teacher]
supervisors: {
collection: "Supervisor",
via: 'office'
},
// Relación con Student. [1 Office to N Student]
students: {
collection: "Student",
via: 'office'
},
toJSON: function() { toJSON: function() {
var office = this.toObject(); var office = this.toObject();
......
...@@ -30,17 +30,18 @@ module.exports = { ...@@ -30,17 +30,18 @@ module.exports = {
size: 40 size: 40
}, },
name: { name: {
required: true,
type: "string", type: "string",
size: 40 size: 40
}, },
surname: { surname: {
required: true,
type: "string", type: "string",
size: 60 size: 60
}, },
role: {
type: "string",
enum: ['tutor', 'therapist', 'office', 'admin']
},
gender: { gender: {
required: true,
type: "string", type: "string",
size: 1 size: 1
}, },
...@@ -88,12 +89,6 @@ module.exports = { ...@@ -88,12 +89,6 @@ module.exports = {
type: 'boolean', type: 'boolean',
columnName: 'arasaac_license' columnName: 'arasaac_license'
}, },
office: {
columnName: 'id_off',
type: 'integer',
required: false,
model: 'Office'
},
// Relación con WorkingSession. [1 Supervisor to N WorkingSession] // Relación con WorkingSession. [1 Supervisor to N WorkingSession]
workingSessions:{ workingSessions:{
collection: "WorkingSession", collection: "WorkingSession",
......
module.exports = function isAdmin (req, res, next) { module.exports = function isAdmin (req, res, next) {
// //
// Only if the user that has connected is global administrator (Yotta employee) // Only if the user that has connected is global administrator (Yotta employee)
// //
if (!req.token || !req.token.isAdmin) if (!req.token || req.token.role !== 'admin')
res.json(401, {error: 'Access denied'}); res.json(401, {error: 'Access denied'});
// Finally, if the user has a clean record, we'll call the `next()` function // Finally, if the user has a clean record, we'll call the `next()` function
// to let them through to the next policy or our controller // to let them through to the next policy or our controller
next(); next();
}; };
\ No newline at end of file
module.exports = function isAdmin (req, res, next) {
//
// Only if the user that has connected is global administrator (Yotta employee)
//
if (!req.token || !req.token.isAdmin && !req.token.isSupAdmin)
res.json(401, {error: 'Access denied'});
// Finally, if the user has a clean record, we'll call the `next()` function
// to let them through to the next policy or our controller
next();
};
module.exports = function isSupAdmin (req, res, next) {
//
// A SupAdmin is a supervisor that is administrator of an office
// That means that we can find its id at the admin column in an entry at the office table
if (!req.token || !req.token.isSupAdmin)
res.json(401, {error: 'Access denied'});
// Finally, if the user has a clean record, we'll call the `next()` function
// to let them through to the next policy or our controller
next();
};
\ No newline at end of file
/* global sails, Student */ /* global sails, Student */
module.exports = function isSupervisorOfStudent(req, res, next) { module.exports = function isSupervisorOfStudent(req, res, next) {
const supervisorId = req.token.id;
const studentId = req.params.id_stu;
if (!studentId || !supervisorId) { if (!req.params.id_stu || !req.token.id)
sails.log.error('This request needs an id_stu parameter and a authenticated supervisor'); return res.json(401, {error: 'Access denied'});
res.json(401, { error: 'Access denied' });
} else { Student.supervisors(req.params.id_stu, function(err, sups) {
Student.supervisors(studentId, function (err, sups) { if (err || !sups || sups.length == 0)
const studentSupervisorsIds = sups.map((studentSupervisor) => studentSupervisor.id); return res.json(401, {error: "This student has no supervisors associated"});
if (sups.map(function(e) {return e.id}).indexOf(req.token.id) >= 0)
return next(); // Is Supervisor of Student
return res.json(401, {error: "No valid credentials"});
})
.catch((err) => {
return res.json(401, {error: "Student not found"});
});
if (err || studentSupervisorsIds.length === 0) {
sails.log.error(`Student ${studentId} has no supervisor assigned`);
res.json(401, { error: 'Access denied' });
} else if (studentSupervisorsIds.indexOf(supervisorId) < 0) {
sails.log.error(`Supervisor ${supervisorId} is not assigned to Student ${studentId}`);
sails.log.debug(`Student supervisors: ${studentSupervisorsIds}`);
res.json(401, { error: 'Access denied' });
} else {
sails.log.debug(`Supervisor ${supervisorId} is assigned to Student ${studentId}`);
next();
}
});
}
}; };
module.exports = function isSupervisorOfStudentOrIsStudent (req, res, next) {
// sails.log("TOKEN: " + JSON.stringify(req.token));
if (!req.params.id_stu)
return res.json(401, {error: 'Access denied 1'}); // If it is a student, then is ok
if (req.token && req.token.isStudent && req.token.id == req.params.id_stu)
return next();
// Get list of supervisors for the student
Student.supervisors(req.params.id_stu, function(err, sups) {
if (err)
return res.json(401, {error: err});
if (!sups || sups.length == 0)
return res.json(401, {error: "This student has no supervisors associated"});
// if supervisor is not in the list of supervisors
if (sups.map(function(e) {return e.id}).indexOf(req.token.id) < 0)
return res.json(401, {error: 'Access denied 3'});
// Finally, if the user has a clean record, we'll call the `next()` function
// to let them through to the next policy or our controller
next();
});
};
/* global sails, Student */
module.exports = function isSupervisorOfStudentOrIsSupAdmin(req, res, next) {
const supervisorId = req.token.id;
const studentId = req.params.id_stu;
if (!studentId || !supervisorId) {
sails.log.error('This request needs an id_stu parameter and a authenticated supervisor');
return res.json(401, { error: 'Access denied' });
} else {
Student.findOne(studentId)
.then(function (s) {
if (req.token.office && s.office == req.token.office.id && req.token.isSupAdmin)
next();
else {
Student.supervisors(studentId, function (err, sups) {
if (err)
return res.json(401, {error: 'Access denied'});
var supIds = sups.map((studentSupervisor) => studentSupervisor.id);
if (supIds.indexOf(supervisorId) >= 0)
return next();
sails.log.error(`Supervisor ${supervisorId} is not assigned to Student ${studentId}`);
return res.json(401, { error: 'Access denied' });
});
}
})
.catch((err) => {
sails.log.error(JSON.stringify(err));
return res.json(401, { error: "No student found" })
});
}
};
module.exports = function isSupervisorOfStudentOrIsSupAdminOrIsStudent (req, res, next) {
// sails.log("TOKEN: " + JSON.stringify(req.token));
if (!req.params.id_stu)
return res.json(401, {error: 'Access denied 1'});
Student.findOne(req.params.id_stu)
.then(function (s) {
if (req.token && req.token.isStudent && req.token.id == req.params.id_stu)
return next(); // Is Student
if (req.token.office && s.office == req.token.office.id && req.token.isSupAdmin)
return next(); // Is Office's administrator
Student.supervisors(req.params.id_stu, function(err, sups) {
if (err || !sups || sups.length == 0)
return res.json(401, {error: "This student has no supervisors associated"});
if (sups.map(function(e) {return e.id}).indexOf(req.token.id) >= 0)
return next(); // Is Supervisor of Student
return res.json(401, {error: "No valid credentials"});
});
})
.catch((err) => {
return res.json(401, {error: "Student not found"});
});
};
...@@ -60,7 +60,6 @@ function LoginCtrl( ...@@ -60,7 +60,6 @@ function LoginCtrl(
$http $http
.post(config.backend + '/sup/login', $scope.credentials) .post(config.backend + '/sup/login', $scope.credentials)
.success(function (data) { .success(function (data) {
data.user.isTutor = data.user.role == 'tutor';
$window.sessionStorage.token = data.token; $window.sessionStorage.token = data.token;
//User data correct //User data correct
...@@ -68,10 +67,15 @@ function LoginCtrl( ...@@ -68,10 +67,15 @@ function LoginCtrl(
// Adapt language en-us to en-gb (the latter is the one supported for 'en') // Adapt language en-us to en-gb (the latter is the one supported for 'en')
if (data.user.lang === 'en-us') if (data.user.lang === 'en-us')
data.user.lang = 'en-gb'; data.user.lang = 'en-gb';
data.user.isTutor = data.user.role == 'tutor';
data.user.isTherapist = data.user.role == 'therapist';
data.user.isOffice = data.user.role == 'office';
data.user.isAdmin = data.user.role == 'admin';
$scope.lang = data.user.lang; $scope.lang = data.user.lang;
$translate.use($scope.lang); $translate.use($scope.lang);
} else { } else {
//No user data, use default lang
$translate.use($scope.lang); $translate.use($scope.lang);
} }
...@@ -80,7 +84,7 @@ function LoginCtrl( ...@@ -80,7 +84,7 @@ function LoginCtrl(
ngToast.success($translate('login_success')); ngToast.success($translate('login_success'));
// Name in login success message // Name in login success message
$scope.name = data.user.name; $scope.name = data.user.name || data.user.email;
// Redirección // Redirección
$location.path('/students'); $location.path('/students');
...@@ -88,9 +92,7 @@ function LoginCtrl( ...@@ -88,9 +92,7 @@ function LoginCtrl(
.error(function (err) { .error(function (err) {
$scope.submitted = false; $scope.submitted = false;
delete $window.sessionStorage.token; delete $window.sessionStorage.token;
if (err.search("without students") > 0) if (err.search("not been activated") > 0)
ngToast.warning($translate.instant('no_students_for_user'));
else if (err.search("not been activated") > 0)
ngToast.danger($translate.instant('inactive_account')); ngToast.danger($translate.instant('inactive_account'));
else else
ngToast.danger($translate.instant("login_fail")); ngToast.danger($translate.instant("login_fail"));
...@@ -109,7 +111,7 @@ function LoginCtrl( ...@@ -109,7 +111,7 @@ function LoginCtrl(
email: '', email: '',
password: '', password: '',
password_confirm: '', password_confirm: '',
lang: '00', lang: '',
role: '', role: '',
}; };
...@@ -129,6 +131,7 @@ $scope.signup = function (formName) { ...@@ -129,6 +131,7 @@ $scope.signup = function (formName) {
var form; var form;
// select form according to account
if (formName == 'tutorForm') if (formName == 'tutorForm')
form = $scope.forms.tutorForm; form = $scope.forms.tutorForm;
else if (formName == 'therapistForm') else if (formName == 'therapistForm')
...@@ -136,6 +139,12 @@ $scope.signup = function (formName) { ...@@ -136,6 +139,12 @@ $scope.signup = function (formName) {
else else
form = $scope.forms.officeForm; form = $scope.forms.officeForm;
// set language according to interface settings
$scope.formdata.lang = $translate.use();
//
// check validity of fields
//
if (typeof $scope.formdata.email == 'undefined' || form.email.$invalid) { if (typeof $scope.formdata.email == 'undefined' || form.email.$invalid) {
ngToast.danger($translate.instant('email_invalid')); ngToast.danger($translate.instant('email_invalid'));
return; return;
......
/* global dashboardControllers */
'use strict';
//-------------------
// SignIn Controller
//-------------------
dashboardControllers.controller('SignInCtrl',
function SignInCtrl($scope,
$http,
$window,
$translate,
$rootScope,
config,
CONSTANTS,
ngToast,
vcRecaptchaService)
{
$scope.reset = function () {
$scope.formdata = {
name: '',
surname: '',
address: '',
postalCode: '',
country: '00',
phone: '',
gender: 'F',
email: '',
email_confirm: '',
password: '',
password_confirm: '',
lang: '00',
role: 'therapist_office',
office: {
name: '',
address: '',
postalCode: '',
country: '00',
contactPerson: '',
phone1: '',
email: '',
logoUrl: ''
},
id_off: -1
};
};
$scope.reset();
// Signup form submit
$scope.signup = function () {
// Validate email match
if ($scope.formdata.email !== $scope.formdata.email_confirm) {
ngToast.danger({ content: $translate.instant('email_match') });
return;
}
// Validate password match
if ($scope.formdata.password !== $scope.formdata.password_confirm) {
ngToast.danger({ content: $translate.instant('password_match') });
return;
}
if ($scope.formdata.password.length < CONSTANTS.password_minlength) {
ngToast.danger({ content: $translate.instant('password_short', {minlength: CONSTANTS.password_minlength}) });
return;
}
if ($scope.formdata.country == '00') {
ngToast.danger({ content: $translate.instant('country_requested') });
return;
}
if (($scope.formdata.role == 'therapist_office' || $scope.formdata.role == 'tutor_office') && $scope.formdata.id_off == -1) {
ngToast.danger({ content: $translate.instant('select_office') });
return;
}
if ($scope.formdata.role == 'therapist_nooffice' && $scope.formdata.office.country == '00') {
ngToast.danger({ content: $translate.instant('country_office_requested') });
return;
}
if (!$scope.formdata.disclaimer_accepted) {
ngToast.danger({ content: $translate.instant('disclaimer_requested') });
return;
}
if (!$scope.formdata.role) {
ngToast.danger({ content: $translate.instant('case_requested') });
return;
}
if (!$scope.signInForm.$valid)
return;
$scope.showdialog = true;
if ($scope.formdata.id_off == -1)
delete $scope.formdata.id_off;
if ($scope.formdata.role === 'tutor_nooffice') {
$scope.formdata.office.name = 'no_office';
$scope.formdata.office.address = $scope.formdata.address;
$scope.formdata.office.postalCode = $scope.formdata.postalCode;
$scope.formdata.office.country = $scope.formdata.country;
$scope.formdata.office.contactPerson = $scope.formdata.name + " " + $scope.formdata.surname;
$scope.formdata.office.phone1 = $scope.formdata.phone;
$scope.formdata.office.email = $scope.formdata.email;
$scope.formdata.office.lang = $scope.formdata.lang;
}
$http
.post(config.backend + '/sup', $scope.formdata)
.success(function () {
ngToast.success({ content: $translate.instant('user_created', { name: $scope.formdata.name, surname: $scope.formdata.surname }) });
$scope.reset();
})
.error(function () {
ngToast.danger({ content: $translate.instant('user_exists', {email: $scope.formdata.email}) });
});
};
});
...@@ -164,11 +164,11 @@ ...@@ -164,11 +164,11 @@
<label translate>password</label> <label translate>password</label>
<div class="form-group"> <div class="form-group">
<input type="password" class="form-control" id="signin_password1" placeholder="{{ 'password_type' | translate }}" name="password" required ng-model="formdata.password"/> <input type="password" class="form-control" id="signin_password1" placeholder="{{ 'password_type' | translate }}" name="password" required ng-model="formdata.password"/>
<span class="color_red text_sm pull-right" ng-show="formdata.password.length < minlength && forms.tutorForm.password.$dirty && forms.tutorForm.password_confirm.$dirty"> {{ 'password_short' | translate:'{ minlength: minlength }' }}</span>
</div> </div>
<div class="form-group"> <div class="form-group">
<input type="password" class="form-control" id="signin_password2" placeholder="{{ 'password_confirm' | translate }}" name="password_confirm" required ng-model="formdata.password_confirm"/> <input type="password" class="form-control" id="signin_password2" placeholder="{{ 'password_confirm' | translate }}" name="password_confirm" required ng-model="formdata.password_confirm"/>
<span class="color_red text_sm pull-right" ng-show="formdata.password != formdata.password_confirm && forms.tutorForm.password.$dirty && forms.tutorForm.password_confirm.$dirty" translate>password_match</span> <span class="color_red text_sm pull-right" ng-show="formdata.password != formdata.password_confirm && forms.tutorForm.password.$dirty && forms.tutorForm.password_confirm.$dirty" translate>password_match</span>
<span class="color_red text_sm pull-right" ng-show="formdata.password.length < minlength && forms.tutorForm.password.$dirty && forms.tutorForm.password_confirm.$dirty"> {{ 'password_short' | translate:'{ minlength: minlength }' }}</span>
</div> </div>
</fieldset> </fieldset>
<div class="form-group"> <div class="form-group">
...@@ -210,16 +210,18 @@ ...@@ -210,16 +210,18 @@
<div class="form-group col-md-4" id="tutor_form"> <div class="form-group col-md-4" id="tutor_form">
<div class="form-group"> <div class="form-group">
<label translate>email</label> <label translate>email</label>
<input type="email" class="form-control" placeholder="{{ 'email' | translate }}" ng-model="formdata.email"/> <input type="email" class="form-control" name="email" placeholder="{{ 'email' | translate }}" ng-model="formdata.email"/>
<span class="color_red text_sm pull-right" ng-show="forms.therapistForm.email.$dirty && forms.therapistForm.email.$invalid" translate>email_invalid</span>
</div> </div>
<fieldset> <fieldset>
<label translate>password</label> <label translate>password</label>
<div class="form-group"> <div class="form-group">
<span class="color_red text_sm pull-right" ng-show="formdata.password != formdata.password_confirm" translate>password_match</span> <input type="password" class="form-control" id="signin_password1" placeholder="{{ 'password_type' | translate }}" name="password" required ng-model="formdata.password"/>
<input type="password" class="form-control" id="signin_password1" placeholder="{{ 'password_type' | translate }}" required ng-model="formdata.password"/> <span class="color_red text_sm pull-right" ng-show="formdata.password.length < minlength && forms.therapistForm.password.$dirty && forms.therapistForm.password_confirm.$dirty"> {{ 'password_short' | translate:'{ minlength: minlength }' }}</span>
</div> </div>
<div class="form-group"> <div class="form-group">
<input type="password" class="form-control" id="signin_password2" placeholder="{{ 'password_confirm' | translate }}" required ng-model="formdata.password_confirm"/> <input type="password" class="form-control" id="signin_password2" placeholder="{{ 'password_confirm' | translate }}" name="password_confirm" required ng-model="formdata.password_confirm"/>
<span class="color_red text_sm pull-right" ng-show="formdata.password != formdata.password_confirm && forms.therapistForm.password.$dirty && forms.therapistForm.password_confirm.$dirty" translate>password_match</span>
</div> </div>
</fieldset> </fieldset>
<div class="form-group"> <div class="form-group">
...@@ -237,7 +239,7 @@ ...@@ -237,7 +239,7 @@
<button class="btn btn-default" ng-click="slide.leftTo('accounts')">&lt;&lt; {{ 'back' | translate }} </button> <button class="btn btn-default" ng-click="slide.leftTo('accounts')">&lt;&lt; {{ 'back' | translate }} </button>
</div> </div>
<div class="col-md-4"> <div class="col-md-4">
<button type="submit" class="btn btn-primary" ng-disabled="forms.therapistForm.$invalid" ng-click="slide.rightTo('confirmation')">{{ 'create_account' | translate }} &gt;&gt; </button> <button type="submit" class="btn btn-primary" ng-disabled="forms.therapistForm.$invalid || !formdata.disclaimer_accepted" ng-click="slide.rightTo('confirmation')">{{ 'create_account' | translate }} &gt;&gt; </button>
</div> </div>
</div> </div>
</div> </div>
...@@ -264,15 +266,18 @@ ...@@ -264,15 +266,18 @@
<div class="form-group"> <div class="form-group">
<label translate>email</label> <label translate>email</label>
<input type="email" class="form-control" placeholder="{{ 'email' | translate }}" required ng-model="formdata.email"/> <input type="email" class="form-control" placeholder="{{ 'email' | translate }}" required ng-model="formdata.email"/>
<span class="color_red text_sm pull-right" ng-show="forms.officeForm.email.$dirty && forms.officeForm.email.$invalid" translate>email_invalid</span>
</div> </div>
<fieldset> <fieldset>
<label translate>password</label> <label translate>password</label>
<span class="color_red text_sm pull-right" ng-show="formdata.password != formdata.password_confirm" translate>password_match</span> <span class="color_red text_sm pull-right" ng-show="formdata.password != formdata.password_confirm" translate>password_match</span>
<div class="form-group"> <div class="form-group">
<input type="password" class="form-control" id="signin_password1" placeholder="{{ 'password_type' | translate }}" required ng-model="formdata.password"/> <input type="password" class="form-control" id="signin_password1" placeholder="{{ 'password_type' | translate }}" name="password" required ng-model="formdata.password"/>
<span class="color_red text_sm pull-right" ng-show="formdata.password.length < minlength && forms.officeForm.password.$dirty && forms.officeForm.password_confirm.$dirty"> {{ 'password_short' | translate:'{ minlength: minlength }' }}</span>
</div> </div>
<div class="form-group"> <div class="form-group">
<input type="password" class="form-control" id="signin_password2" placeholder="{{ 'password_confirm' | translate }}" required ng-model="formdata.password_confirm"/> <input type="password" class="form-control" id="signin_password2" placeholder="{{ 'password_confirm' | translate }}" name="password_confirm" required ng-model="formdata.password_confirm"/>
<span class="color_red text_sm pull-right" ng-show="formdata.password != formdata.password_confirm && forms.officeForm.password.$dirty && forms.officeForm.password_confirm.$dirty" translate>password_match</span>
</div> </div>
</fieldset> </fieldset>
<div class="form-group"> <div class="form-group">
......
...@@ -24,15 +24,15 @@ dashboardControllers.controller('SupervisorCtrl', function SupervisorCtrl( ...@@ -24,15 +24,15 @@ dashboardControllers.controller('SupervisorCtrl', function SupervisorCtrl(
// Assign values this way (like an object) to ensure it's the parent scope // Assign values this way (like an object) to ensure it's the parent scope
$scope.user.id = user.id; $scope.user.id = user.id;
$scope.user.role = user.role;
$scope.user.name = user.name; $scope.user.name = user.name;
$scope.user.surname = user.surname; $scope.user.surname = user.surname;
$scope.user.pic = user.pic; $scope.user.pic = user.pic;
$scope.user.office = user.office;
if ($scope.user.office.name == 'no_office')
$scope.user.office.name = $translate.instant('no_office');
$scope.user.lang = user.lang; $scope.user.lang = user.lang;
$scope.user.isSupAdmin = user.isSupAdmin; $scope.user.isOffice = user.isOffice;
$scope.user.isTutor = user.isTutor; $scope.user.isTutor = user.isTutor;
$scope.user.isAdmin = user.isAdmin;
$scope.user.isTherapist = user.isTherapist;
$scope.user.arasaacLicense = user.arasaacLicense; $scope.user.arasaacLicense = user.arasaacLicense;
// Link to setup // Link to setup
......
...@@ -21,6 +21,8 @@ module.exports.policies = { ...@@ -21,6 +21,8 @@ module.exports.policies = {
'*': false, '*': false,
// TODO: habría que revisar estas políticas, porque creo que hay bastantes brechas abiertas
ActionController: { ActionController: {
create: ['tokenAuth'], create: ['tokenAuth'],
createlist: ['tokenAuth'] createlist: ['tokenAuth']
...@@ -63,7 +65,7 @@ module.exports.policies = { ...@@ -63,7 +65,7 @@ module.exports.policies = {
getAll: true, getAll: true,
get: ['tokenAuth'], get: ['tokenAuth'],
getBasic: true, getBasic: true,
supervisors: ['tokenAuth', 'isAdminOrIsSupAdmin'] supervisors: ['tokenAuth', 'isAdminOrOffice']
}, },
PictoController: { PictoController: {
...@@ -97,11 +99,11 @@ module.exports.policies = { ...@@ -97,11 +99,11 @@ module.exports.policies = {
StudentController: { StudentController: {
eternal: true, eternal: true,
getInfo: ['tokenAuth', 'isSupervisorOfStudentOrIsSupAdminOrIsStudent'], getInfo: ['tokenAuth', 'isStudentOrSupervisorOfStudent'],
supervisors: ['tokenAuth'], supervisors: ['tokenAuth'],
therapists: ['tokenAuth'], therapists: ['tokenAuth'],
tutors: ['tokenAuth'], tutors: ['tokenAuth'],
link_supervisor: ['tokenAuth', 'isSupAdmin'], link_supervisor: ['tokenAuth', 'isOffice'],
pictos: ['tokenAuth'], pictos: ['tokenAuth'],
methods: ['tokenAuth'], methods: ['tokenAuth'],
lasttries: ['tokenAuth'], lasttries: ['tokenAuth'],
...@@ -113,7 +115,7 @@ module.exports.policies = { ...@@ -113,7 +115,7 @@ module.exports.policies = {
update_legend: ['tokenAuth'], update_legend: ['tokenAuth'],
update_category: ['tokenAuth', 'isSupervisorOfStudent'], update_category: ['tokenAuth', 'isSupervisorOfStudent'],
login: true, login: true,
create: ['tokenAuth', 'isSupAdmin'], create: ['tokenAuth', 'isOffice'],
upload: ['tokenAuth'], upload: ['tokenAuth'],
upload_sound: ['tokenAuth'], upload_sound: ['tokenAuth'],
add_picto: ['tokenAuth', 'isSupervisorOfStudent'], add_picto: ['tokenAuth', 'isSupervisorOfStudent'],
...@@ -123,8 +125,8 @@ module.exports.policies = { ...@@ -123,8 +125,8 @@ module.exports.policies = {
action: true, action: true,
config: true, config: true,
actions_batch: ['tokenAuth'], actions_batch: ['tokenAuth'],
delete: ['tokenAuth', 'isSupAdmin'], delete: ['tokenAuth', 'isOffice'],
unlink_supervisor: ['tokenAuth', 'isSupAdmin'], unlink_supervisor: ['tokenAuth', 'isOffice'],
delete_picto: ['tokenAuth', 'isSupervisorOfStudent'], delete_picto: ['tokenAuth', 'isSupervisorOfStudent'],
getActiveScene: ['tokenAuth'], getActiveScene: ['tokenAuth'],
getScenes: ['tokenAuth'], getScenes: ['tokenAuth'],
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment