Added deleting of codes

Fixed issue with all users seeing all codes and uploads
This commit is contained in:
Mark van Renswoude 2018-04-28 09:51:58 +02:00
parent 6f827382ff
commit de7953c6ea
9 changed files with 128 additions and 34 deletions

3
.gitignore vendored
View File

@ -5,4 +5,5 @@ public/dist/*.js
public/dist/index.html
config.js
*.sublime-workspace
npm-debug.log
npm-debug.log
/custom/images/logo.png

View File

@ -23,9 +23,9 @@ async function checkAuthorization(req, res, repository, onVerified)
token = req.headers.authorization.split(' ')[1];
}
else if (req.cookies && req.cookies.token)
else if (req.cookies && req.cookies.adminToken)
{
token = req.cookies.token;
token = req.cookies.adminToken;
}
else
{
@ -78,7 +78,7 @@ module.exports = (repository) =>
await checkAuthorization(req, res, repository, async (user) =>
{
res.send({
userId: user.userId,
userId: user.id,
username: user.username,
auth: user.auth
});
@ -111,7 +111,7 @@ module.exports = (repository) =>
{
await checkAuthorization(req, res, repository, async (user) =>
{
var codes = await repository.codes.getCodes(user.hasAuth(AuthTokens.ViewAllCodes) ? null : user.userId);
var codes = await repository.codes.getCodes(user.hasAuth(AuthTokens.ViewAllCodes) ? null : user.id);
var usernames = await repository.users.getNames();
codes.forEach((item) =>
@ -129,7 +129,7 @@ module.exports = (repository) =>
await checkAuthorization(req, res, repository, async (user) =>
{
var code = await repository.codes.getCode(req.params.code);
if (code === null || (code.userId !== user.userId && !user.hasAuth(AuthTokens.ViewAllCodes)))
if (code === null || (code.userId !== user.id && !user.hasAuth(AuthTokens.ViewAllCodes)))
{
res.sendStatus(404);
return;
@ -153,7 +153,7 @@ module.exports = (repository) =>
if (postedCode.id)
{
var code = await repository.codes.getCode(postedCode.id);
if (code === null || (code.userId !== user.userId && !user.hasAuth(AuthTokens.ViewAllCodes)))
if (code === null || (code.userId !== user.id && !user.hasAuth(AuthTokens.ViewAllCodes)))
{
res.sendStatus(404);
return;
@ -183,6 +183,22 @@ module.exports = (repository) =>
}));
router.delete('/codes/:id', asyncHandler(async (req, res) =>
{
await checkAuthorization(req, res, repository, async (user) =>
{
var code = await repository.codes.getCode(req.params.id);
if (code == null || (code.userId !== user.id && !user.hasAuth(AuthTokens.ViewAllCodes)))
{
res.sendStatus(404);
return;
}
repository.codes.delete(code.id);
res.sendStatus(200);
});
}));
/*
Uploads
*/
@ -190,7 +206,7 @@ module.exports = (repository) =>
{
await checkAuthorization(req, res, repository, async (user) =>
{
var files = await repository.uploads.getUploads(user.hasAuth(AuthTokens.ViewAllUploads) ? null : user.userId);
var files = await repository.uploads.getUploads(user.hasAuth(AuthTokens.ViewAllUploads) ? null : user.id);
var usernames = await repository.users.getNames();
var codedescriptions = await repository.codes.getDescriptions();
@ -210,7 +226,7 @@ module.exports = (repository) =>
await checkAuthorization(req, res, repository, async (user) =>
{
var upload = await repository.uploads.getUpload(req.params.id);
if (upload == null || (upload.userId !== user.userId && !user.hasAuth(AuthTokens.ViewAllUploads)))
if (upload == null || (upload.userId !== user.id && !user.hasAuth(AuthTokens.ViewAllUploads)))
{
res.sendStatus(404);
return;

View File

@ -194,6 +194,26 @@ class CodeRepository
{
return message !== null ? markdown.toHTML(message) : null;
}
delete(code)
{
var self = this;
return new Promise((resolve, reject) =>
{
self.store.remove({ _id: code }, (err, numRemoved) =>
{
if (err)
{
reject(err);
return;
}
resolve();
});
});
}
}

View File

@ -183,4 +183,9 @@ a
margin-left: 180px;
margin-bottom: .5rem;
}
.confirmDelete
{
color: red;
}
</style>

View File

@ -59,7 +59,8 @@ export default {
list: {
code: 'Code',
owner: 'Owner'
owner: 'Owner',
actions: 'Actions'
},
detail: {

View File

@ -59,7 +59,8 @@ export default {
list: {
code: 'Code',
owner: 'Eigenaar'
owner: 'Eigenaar',
actions: 'Acties'
},
detail: {

View File

@ -4,15 +4,22 @@
<div v-if="codes !== null">
<div class="pure-g list-header">
<div class="pure-u-3-4"><span class="text">{{ $t('admin.codes.list.code') }}</span></div>
<div class="pure-u-1-4"><span class="text">{{ $t('admin.codes.list.owner') }}</span></div>
<div class="pure-u-1-2"><span class="text">{{ $t('admin.codes.list.code') }}</span></div>
<div class="pure-u-1-4"><span class="text" v-if="hasAuth('viewAllCodes')">{{ $t('admin.codes.list.owner') }}</span></div>
<div class="pure-u-1-4"><span class="text">{{ $t('admin.codes.list.actions') }}</span></div>
</div>
<div v-for="code in codes" class="list">
<div class="pure-g row">
<div class="pure-u-3-4"><span class="text"><router-link :to="'codes/edit/' + encodeURIComponent(code.id)">{{ code.id }}</router-link></span></div>
<div class="pure-u-1-4"><span class="text">{{ code.username }}</span></div>
<div class="pure-u-1-1" v-if="code.description"><span class="text description">{{ code.description }}</span></div>
<div class="pure-u-1-2">
<span class="text code"><router-link :to="'codes/edit/' + encodeURIComponent(code.id)">{{ code.id }}</router-link></span>
<span class="text description" v-if="code.description">{{ code.description }}</span>
</div>
<div class="pure-u-1-4"><span class="text" v-if="hasAuth('viewAllCodes')">{{ code.username }}</span></div>
<div class="pure-u-1-4">
<button class="pure-button"v-if="confirmDelete == code.id" @click.prevent="cancelDelete"><fa icon="ban"></fa></button>
<button class="pure-button" :class="{ confirmDelete: confirmDelete == code.id }" @click.prevent="deleteClick(code.id)"><fa icon="trash-alt"></fa></button>
</div>
</div>
</div>
@ -35,7 +42,8 @@ export default {
data()
{
return {
codes: null
codes: null,
confirmDelete: null
};
},
@ -53,6 +61,54 @@ export default {
self.codes = _.orderBy(response.data, ['created'], ['desc']);
})
.catch((error) => { shared.$emit('apiError', error, this.$router) });
},
methods: {
hasAuth(token)
{
return shared.user !== null && shared.user.auth.indexOf(token) > -1;
},
deleteClick(codeId)
{
var self = this;
if (self.confirmDelete == codeId)
{
self.confirmDelete = null;
axios.delete('/admin/codes/' + encodeURIComponent(codeId), {
headers: {
Authorization: 'Bearer ' + shared.adminToken
}})
.then((response) =>
{
var index = _.findIndex(self.codes, (item) => { return item.id == codeId; });
if (index > -1)
self.codes.splice(index, 1);
})
.catch((error) => { shared.$emit('apiError', error, this.$router) });
}
else
{
self.confirmDelete = codeId;
}
},
cancelDelete()
{
var self = this;
self.confirmDelete = null;
}
}
}
</script>
</script>
<style lang="scss">
.description
{
display: block;
}
</style>

View File

@ -7,7 +7,7 @@
<menu-link route="/admin/codes" :title="$t('admin.menu.codes')"></menu-link>
<menu-link route="/admin/users" :title="$t('admin.menu.users')" v-if="hasAuth('manageUsers')"></menu-link>
<li class="pure-menu-item right">
<li class="pure-menu-item logout">
<a class="pure-menu-link" href="#" @click.prevent="logout">{{ $t('admin.logout') }}</a>
</li>
</ul>
@ -90,7 +90,7 @@ export default {
}
}
.right
.logout
{
float: right;
}

View File

@ -6,7 +6,7 @@
<div class="pure-g">
<div class="pure-u-1-1"><span class="text codedescription">{{ upload.codedescription || upload.code }}</span></div>
<div class="pure-u-1-3"><span class="text">{{ upload.code }}</span></div>
<div class="pure-u-1-3"><span class="text">{{ upload.username }}</span></div>
<div class="pure-u-1-3"><span class="text" v-if="hasAuth('viewAllUploads')">{{ upload.username }}</span></div>
<div class="pure-u-1-3 right"><span class="text">{{ upload.created | formatDateTime }}</span></div>
</div>
</div>
@ -14,7 +14,7 @@
<div class="pure-menu pure-menu-horizontal">
<ul class="pure-menu-list">
<li class="pure-menu-item" v-if="confirmDelete == upload.id"><a href="#" class="pure-menu-link" @click.prevent="cancelDelete"><fa icon="ban"></fa> {{ $t('admin.cancel') }}</a></li>
<li class="pure-menu-item"><a href="#" class="pure-menu-link" :class="{ confirm: confirmDelete == upload.id }" @click.prevent="deleteClick(upload.id)"><fa icon="trash-alt"></fa> {{ $t('admin.delete') }}</a></li>
<li class="pure-menu-item"><a href="#" class="pure-menu-link" :class="{ confirmDelete: confirmDelete == upload.id }" @click.prevent="deleteClick(upload.id)"><fa icon="trash-alt"></fa> {{ $t('admin.delete') }}</a></li>
</ul>
</div>
@ -76,6 +76,12 @@ export default {
},
methods: {
hasAuth(token)
{
return shared.user !== null && shared.user.auth.indexOf(token) > -1;
},
getFileIconUrl(filename)
{
var ext = this.getExtension(filename);
@ -196,16 +202,4 @@ export default {
{
font-weight: bold;
}
.right
{
text-align: right;
}
.confirm
{
color: red;
}
</style>