Skip to content

Commit

Permalink
Merge pull request #436 from mboudet/master
Browse files Browse the repository at this point in the history
Release 1.4.29?
  • Loading branch information
mboudet authored Feb 6, 2024
2 parents b0419fd + 8ae6d92 commit 83e03d6
Show file tree
Hide file tree
Showing 47 changed files with 823 additions and 206 deletions.
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
# Changelog

## 1.4.29

* Various security PR merged
* Add ordering to most admin tables
* Add user registration date to the 'Pending admin approval' and 'Pending email approval' table, and remove user ID
* Updated buttons to make them more visible
* Allow group creation on the user page
* Set group owner as 'optional'
* Allow otp removal for users and admins
* Allow user expiration without sending a mail for gomail
* Allow admin 'unlock' of a locked (3 time wrong login) account
* Fix tag creation crash
* Allow a pending project edition without validating it.
* Add optional description to group

## 1.4.28

* Fix security check for user identity when making API calls
Expand Down
3 changes: 3 additions & 0 deletions app.js
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,7 @@ app.post('/user/:id/quota', users);
app.delete('/user/:id/cloud', users);
app.post('/user/:id/group/:group', users);
app.get('/user/:id/subscribed', users);
app.get('/user/:id/unlock', users);
app.put('/user/:id/subscribe', users);
app.put('/user/:id/unsubscribe', users);
app.delete('/user/:id/group/:group', users);
Expand All @@ -349,6 +350,7 @@ app.get('/project/:id', projects);
app.post('/project', projects);
app.post('/project/:id', projects);
app.post('/project/:id/request', projects);
app.put('/project', projects);
app.delete('/project/:id', projects);
app.put('/project/:id/request', projects);
app.get('/project/:id/extend', projects);
Expand Down Expand Up @@ -376,6 +378,7 @@ app.post('/u2f/register/:id', auth);
app.get('/u2f/auth/:id', auth);
app.post('/u2f/auth/:id', auth);
app.post('/otp/register/:id', auth);
app.delete('/otp/register/:id', auth);
app.post('/otp/check/:id', auth);
app.get('/mail/auth/:id', auth);
app.post('/mail/auth/:id', auth);
Expand Down
4 changes: 2 additions & 2 deletions core/group.service.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,10 @@ function get_group_home(user) {
}


async function create_group(group_name, owner_name, action_owner = 'auto', add_owner=true) {
async function create_group(group_name, owner_name, description, action_owner = 'auto', add_owner=true) {
let mingid = await idsrv.getGroupAvailableId();
let fid = new Date().getTime();
let group = {name: group_name, gid: mingid, owner: owner_name};
let group = {name: group_name, gid: mingid, owner: owner_name, description: description};
try {
await dbsrv.mongo_groups().insertOne(group);
await goldap.add_group(group, fid);
Expand Down
20 changes: 13 additions & 7 deletions core/notif_gomail.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const dbsrv = require('../core/db.service.js');

var mail_set = false;

const gomailAgent = new https.Agent({
const gomailAgent = new https.Agent({
rejectUnauthorized: CONFIG.gomail.force_tls ? true : false
});

Expand Down Expand Up @@ -145,23 +145,29 @@ module.exports = {
}
},

remove: async function(email) {
remove: async function(email, sendmail=true) {
if(email===undefined ||email===null || email=='' || ! mail_set) {
return;
}
if(email.indexOf('@fake')>-1){
return;
}

let data = {
'email': [email],
'message': CONFIG.gomail.optout_message,
'message_html': CONFIG.gomail.optout_message_html,
};

if (!sendmail){
data['skip'] = true;
}

try {
await axios.delete(
gomailUrl + '/mail/opt/' + CONFIG.gomail.main_list,
{
data: {
'email': [email],
'message': CONFIG.gomail.optout_message,
'message_html': CONFIG.gomail.optout_message_html
},
data: data,
headers: gomailHeaders,
httpsAgent: gomailAgent
}
Expand Down
23 changes: 12 additions & 11 deletions core/notif_listmonk.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ var mail_set = false;

var transporter = null;

const listMonkAgent = new https.Agent({
const listMonkAgent = new https.Agent({
rejectUnauthorized: CONFIG.listmonk.force_tls ? true : false
});

Expand Down Expand Up @@ -53,7 +53,7 @@ async function create_user(user) {
console.error('[create_user] error', err);
return null;
}

}

async function delete_user(user) {
Expand Down Expand Up @@ -86,7 +86,7 @@ async function get_user(email) {
});
} catch(err) {
console.error('[get_user] error', err);
return null;
return null;
}
let users = res.data.data.results;
for(let i=0;i<users.length;i++){
Expand Down Expand Up @@ -114,7 +114,7 @@ async function join_list(user, lists) {
}
add_lists.push(list.id);
}

let changed = false;
for(let l=0;l<add_lists.length;l++){
if (user.lists.indexOf(add_lists[l])<0) {
Expand Down Expand Up @@ -147,7 +147,7 @@ async function join_list(user, lists) {
});
} catch(err) {
console.error('[join_list] error', err);
return false;
return false;
}
return true;
}
Expand Down Expand Up @@ -190,7 +190,7 @@ async function quit_list(user, lists) {
});
} catch(err) {
console.error('[quit_list] error', err);
return false;
return false;
}
return true;
}
Expand All @@ -207,7 +207,7 @@ async function update_user(user) {
});
} catch(err) {
console.error('[update_user] error', err);
return false;
return false;
}
return true;
}
Expand All @@ -225,7 +225,7 @@ async function get_lists() {
return lists.data.data.results;
} catch(err) {
console.error('[get_lists] error', err);
return null;
return null;
}
}

Expand Down Expand Up @@ -256,7 +256,7 @@ async function get_list_members(list_id) {
return members.data.data.results;
} catch(err) {
console.error('[get_list_members] error', err);
return [];
return [];
}
}

Expand Down Expand Up @@ -350,7 +350,8 @@ module.exports = {
return;
},

remove: async function(email) {
// eslint-disable-next-line no-unused-vars
remove: async function(email, sendmail=true) {
if(email===undefined ||email===null || email=='' || ! mail_set) {
return;
}
Expand All @@ -366,7 +367,7 @@ module.exports = {
return;
}


let ok = await quit_list(user, CONFIG.listmonk.optout);
if (ok) {
dbsrv.mongo_events().insertOne({'date': new Date().getTime(), 'action': 'remove ' + email + ' from mailing list ' + CONFIG.listmonk.optout.join(',') , 'logs': []});
Expand Down
3 changes: 2 additions & 1 deletion core/notif_nodemailer.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,8 @@ module.exports = {
},

// todo: should be factorized with add, as there is only small difference
remove: async function(email) {
// eslint-disable-next-line no-unused-vars
remove: async function(email, sendmail=true) {
if (CONFIG.nodemailer.list) {
if(email===undefined ||email===null || email=='' || ! mail_set) {
return;
Expand Down
8 changes: 8 additions & 0 deletions core/project.service.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ exports.remove_project = remove_project;
exports.update_project = update_project;
exports.create_project_request = create_project_request;
exports.remove_project_request = remove_project_request;
exports.edit_project = edit_project;

async function create_project(new_project, uuid, action_owner = 'auto') {
logger.info('Create Project ' + new_project.id + ' uuid ' + uuid);
Expand Down Expand Up @@ -72,6 +73,13 @@ async function remove_project(id, action_owner = 'auto') {

}

async function edit_project(project, uuid, action_owner = 'auto') {
logger.info('Editing Project ' + project.id);
project.expiration_notif = 0;
await dbsrv.mongo_pending_projects().updateOne({'uuid': uuid}, {'$set': project});
await dbsrv.mongo_events().insertOne({'owner': action_owner, 'date': new Date().getTime(), 'action': 'update project ' + project.id , 'logs': []});
}

async function update_project(id, project, action_owner = 'auto') {
logger.info('Update Project ' + id);
project.expiration_notif = 0;
Expand Down
9 changes: 9 additions & 0 deletions core/user.service.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ exports.remove_user_from_project = remove_user_from_project;
exports.activate_user = activate_user;
exports.new_password = new_password;
exports.new_random = new_random;
exports.is_active = is_active;

function new_random(len=16) {
return crypto.randomBytes(32).toString('hex').slice(0,len);
Expand All @@ -59,6 +60,10 @@ function new_password(len=16) {
});
}

function is_active(user){
return user.status === STATUS_ACTIVE;
}

// module functions
function get_user_home(user) {
if (!user.uid || user.uid.length <= 1) {
Expand Down Expand Up @@ -191,6 +196,10 @@ async function create_user(user, action_owner = 'auto') {
}
}

if(!user.registration) {
user.registration = new Date().getTime();
}

user.loginShell = '/bin/bash';

// create from script as ui add a register action in history
Expand Down
16 changes: 11 additions & 5 deletions manager2/src/app/admin/databases/databases.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ <h3>Databases</h3>
[rowsPerPageOptions]="[10,25,50]"
[globalFilterFields]="['name', 'type', 'host', 'owner']"
[filterDelay]="0"
sortMode="multiple"
>
<ng-template pTemplate="caption">
<div class="table-header">
Expand All @@ -21,12 +22,17 @@ <h3>Databases</h3>
</div>
</ng-template>
<ng-template pTemplate="header">
<tr><th>Name</th><th>Owner</th><th>Type</th><th>Host</th></tr>
<tr>
<th pSortableColumn="name">Name <p-sortIcon field="name"</th>
<th pSortableColumn="owner">Owner <p-sortIcon field="owner"</th>
<th pSortableColumn="type">Type <p-sortIcon field="type"</th>
<th pSortableColumn="host">Host <p-sortIcon field="host"</th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-database>
<tr>
<td><span class="label label-primary">{{database.name}}</span></td>
<td><a routerLink="/user/{{database.owner}}"><span class="label label-primary">{{database.owner}}</span></a></td>
<td><span>{{database.name}}</span></td>
<td><a routerLink="/user/{{database.owner}}"><span class="p-button p-button-sm p-button-primary">{{database.owner}}</span></a></td>
<td>{{database.type}}</td>
<td>{{database.host}}</td>
</tr>
Expand Down Expand Up @@ -71,7 +77,7 @@ <h3>Declare existing database (no creation)</h3>
</div>
<div class="col-sm-1">
<label style="opacity: 0;" class="control-label">Create</label>
<button type="button" class="btn btn-secondary" (click)="declare_db()">Declare DB</button>
<button type="button" class="p-button p-button-sm p-button-secondary" (click)="declare_db()">Declare DB</button>
</div>
</div>
</form>
Expand Down Expand Up @@ -103,7 +109,7 @@ <h3>Change database owner</h3>
</div>
<div class="col-sm-2">
<label for="modifyOwner" style="opacity: 0;">Modify</label>
<button id="modifyOwner" type="button" class="btn btn-secondary" (click)="changeOwner()" class="form-control">Modify</button>
<button id="modifyOwner" type="button" class="p-button p-button-sm p-button-secondary" (click)="changeOwner()" class="form-control">Modify</button>
</div>
</div>
</form>
Expand Down
33 changes: 23 additions & 10 deletions manager2/src/app/admin/groups/groups.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@ <h3 class="panel-title">Group creation</h3>
<input placeholder="Owner" type="text" [ngModelOptions]="{standalone: true}" [(ngModel)]="new_group.owner" class="form-control"/>
</div>
<div class="form-group">
<button type="button" class="btn btn-secondary" (click)="addGroup()">Create</button>
<input placeholder="Description" type="text" [ngModelOptions]="{standalone: true}" [(ngModel)]="new_group.description" class="form-control"/>
</div>
<div class="form-group">
<button type="button" class="p-button p-button-sm p-button-secondary" (click)="addGroup()">Create</button>
</div>
</form>
</div>
Expand Down Expand Up @@ -47,7 +50,11 @@ <h3>Users in group {{selectedGroup.name}}</h3>
<div class="col-sm-3">
<input placeholder="Owner" id="group_id" type="text" [ngModelOptions]="{standalone: true}" [(ngModel)]="selectedGroup.owner" class="form-control"/>
</div>
<button type="button" class="btn btn-secondary" (click)="updateGroup()">Update</button>
<label for="group_desc" class="col-sm-2 col-form-label">Description</label>
<div class="col-sm-6">
<input placeholder="Description" id="group_desc" type="text" [ngModelOptions]="{standalone: true}" [(ngModel)]="selectedGroup.description" class="form-control"/>
</div>
<button type="button" class="p-button p-button-sm p-button-secondary" (click)="updateGroup()">Update</button>
</div>
<div class="form-group">

Expand Down Expand Up @@ -81,15 +88,15 @@ <h5>Group members</h5>
</ng-template>
<ng-template pTemplate="body" let-user>
<tr>
<td><a routerLink="/user/{{user.uid}}"><span class="label label-primary">{{user.uid}}</span></a></td>
<td><a routerLink="/user/{{user.uid}}"><span class="p-button p-button-sm p-button-primary">{{user.uid}}</span></a></td>
<td>{{user.email}}</td>
<td><span *ngIf="user.authorized">x</span></td>
<td><span *ngIf="user.group == selectedGroup.name">x</span></td>
</tr>
</ng-template>
</p-table>
</div>
<button class="btn btn-danger" (click)="delete_group(selectedGroup)">Delete</button>
<button class="p-button p-button-sm p-button-danger" (click)="delete_group(selectedGroup)">Delete</button>
</div>
</div>
</div>
Expand All @@ -106,8 +113,9 @@ <h3>Groups</h3>
[rows]="10"
[showCurrentPageReport]="true"
[rowsPerPageOptions]="[10,25,50]"
[globalFilterFields]="['name', 'gid', 'owner']"
[globalFilterFields]="['name', 'gid', 'owner', 'tags', 'description']"
[filterDelay]="0"
sortMode="multiple"
>
<ng-template pTemplate="caption">
<div class="table-header">
Expand All @@ -119,15 +127,20 @@ <h3>Groups</h3>
</ng-template>
<ng-template pTemplate="header">
<tr>
<th>Group</th>
<th>gid</th>
<th>owner</th>
</tr> </ng-template>
<th pSortableColumn="name">Group <p-sortIcon field="name"></p-sortIcon></th>
<th pSortableColumn="gid">Gid <p-sortIcon field="gid"></p-sortIcon></th>
<th pSortableColumn="owner">Owner <p-sortIcon field="owner"></p-sortIcon></th>
<th pSortableColumn="description">Description <p-sortIcon field="description"></p-sortIcon></th>
<th pSortableColumn="tags">Tags <p-sortIcon field="tags"></p-sortIcon></th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-group>
<tr>
<td (click)="show_group_users(group)" style="cursor: pointer;"><span class="label label-primary">{{group.name}}</span></td>
<td (click)="show_group_users(group)" style="cursor: pointer;"><span class="p-button p-button-sm p-button-primary">{{group.name}}</span></td>
<td>{{group.gid}}</td>
<td>{{group.owner}}</td>
<td>{{group.description}}</td>
<td>{{group.tags ? group.tags.join(", ") : ""}}</td>
</tr>
</ng-template>
</p-table>
Expand Down
Loading

0 comments on commit 83e03d6

Please sign in to comment.