Compare commits
No commits in common. "aa96f49ae12ff65b8f64ee23d30a376406c6bf35" and "9b8bcd0722cbe2c67b127da0d17c1f312cb51b14" have entirely different histories.
aa96f49ae1
...
9b8bcd0722
|
@ -10,5 +10,4 @@ module.exports = {
|
||||||
signatures: '/signatures',
|
signatures: '/signatures',
|
||||||
squads: '/squads',
|
squads: '/squads',
|
||||||
users: '/users',
|
users: '/users',
|
||||||
account: '/account'
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -5,6 +5,7 @@ let check = (requiredPermission, actualPermission, res, next) => {
|
||||||
if (actualPermission >= requiredPermission) {
|
if (actualPermission >= requiredPermission) {
|
||||||
return next();
|
return next();
|
||||||
}
|
}
|
||||||
|
|
||||||
return res.status(403).send({
|
return res.status(403).send({
|
||||||
success: false,
|
success: false,
|
||||||
message: 'permission denied'
|
message: 'permission denied'
|
||||||
|
|
|
@ -13,11 +13,6 @@ const AppUserSchema = new Schema({
|
||||||
type: String,
|
type: String,
|
||||||
required: true
|
required: true
|
||||||
},
|
},
|
||||||
squad: {
|
|
||||||
type: mongoose.Schema.Types.ObjectId,
|
|
||||||
ref: 'Squad',
|
|
||||||
default: null
|
|
||||||
},
|
|
||||||
permission: {
|
permission: {
|
||||||
type: Number,
|
type: Number,
|
||||||
get: v => Math.round(v),
|
get: v => Math.round(v),
|
||||||
|
@ -25,14 +20,6 @@ const AppUserSchema = new Schema({
|
||||||
min: 0,
|
min: 0,
|
||||||
max: 4,
|
max: 4,
|
||||||
default: 0
|
default: 0
|
||||||
},
|
|
||||||
secret: {
|
|
||||||
type: String,
|
|
||||||
required: true
|
|
||||||
},
|
|
||||||
activated: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
collection: 'app_user',
|
collection: 'app_user',
|
||||||
|
|
|
@ -1,90 +0,0 @@
|
||||||
"use strict";
|
|
||||||
|
|
||||||
// modules
|
|
||||||
const express = require('express');
|
|
||||||
const logger = require('debug')('cc:awardings');
|
|
||||||
|
|
||||||
// HTTP status codes by name
|
|
||||||
const codes = require('./http-codes');
|
|
||||||
|
|
||||||
const routerHandling = require('../middleware/router-handling');
|
|
||||||
|
|
||||||
// Mongoose Model using mongoDB
|
|
||||||
const AppUserModel = require('../models/app-user');
|
|
||||||
|
|
||||||
const account = express.Router();
|
|
||||||
|
|
||||||
|
|
||||||
account.route('/')
|
|
||||||
.get((req, res, next) => {
|
|
||||||
AppUserModel.find({}).populate('squad').exec((err, items) => {
|
|
||||||
if (err) {
|
|
||||||
err.status = codes.servererror;
|
|
||||||
return next(err);
|
|
||||||
}
|
|
||||||
res.locals.items = items;
|
|
||||||
res.locals.processed = true;
|
|
||||||
next();
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.all(
|
|
||||||
routerHandling.httpMethodNotAllowed
|
|
||||||
);
|
|
||||||
|
|
||||||
// routes **********************
|
|
||||||
account.route('/:id')
|
|
||||||
.patch((req, res, next) => {
|
|
||||||
if (!req.body || (req.body._id && req.body._id !== req.params.id)) {
|
|
||||||
// little bit different as in PUT. :id does not need to be in data, but if the _id and url id must match
|
|
||||||
const err = new Error('id of PATCH resource and send JSON body are not equal ' + req.params.id + " " + req.body._id);
|
|
||||||
err.status = codes.notfound;
|
|
||||||
next(err);
|
|
||||||
return; // prevent node to process this function further after next() has finished.
|
|
||||||
}
|
|
||||||
|
|
||||||
// increment version manually as we do not use .save(.)
|
|
||||||
req.body.updatedAt = new Date();
|
|
||||||
req.body.$inc = {__v: 1};
|
|
||||||
|
|
||||||
// PATCH is easier with mongoose than PUT. You simply update by all data that comes from outside. no need to reset attributes that are missing.
|
|
||||||
AppUserModel.findByIdAndUpdate(req.params.id, req.body, {new: true}).populate('squad').exec((err, item) => {
|
|
||||||
if (err) {
|
|
||||||
err.status = codes.wrongrequest;
|
|
||||||
}
|
|
||||||
else if (!item) {
|
|
||||||
err = new Error("appUser not found");
|
|
||||||
err.status = codes.notfound;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
res.locals.items = item;
|
|
||||||
}
|
|
||||||
next(err);
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
.delete((req, res, next) => {
|
|
||||||
AppUserModel.findByIdAndRemove(req.params.id, (err, item) => {
|
|
||||||
if (err) {
|
|
||||||
err.status = codes.wrongrequest;
|
|
||||||
}
|
|
||||||
else if (!item) {
|
|
||||||
err = new Error("item not found");
|
|
||||||
err.status = codes.notfound;
|
|
||||||
}
|
|
||||||
// we don't set res.locals.items and thus it will send a 204 (no content) at the end. see last handler user.use(..)
|
|
||||||
res.locals.processed = true;
|
|
||||||
next(err); // this works because err is in normal case undefined and that is the same as no parameter
|
|
||||||
});
|
|
||||||
})
|
|
||||||
|
|
||||||
.all(
|
|
||||||
routerHandling.httpMethodNotAllowed
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
// this middleware function can be used, if you like or remove it
|
|
||||||
// it looks for object(s) in res.locals.items and if they exist, they are send to the client as json
|
|
||||||
account.use(routerHandling.emptyResponse);
|
|
||||||
|
|
||||||
|
|
||||||
module.exports = account;
|
|
|
@ -8,9 +8,6 @@ const Q = require('q');
|
||||||
const _ = require('lodash');
|
const _ = require('lodash');
|
||||||
const logger = require('debug')('cc:authenticate');
|
const logger = require('debug')('cc:authenticate');
|
||||||
|
|
||||||
const apiAuthenticationMiddleware = require('../middleware/auth-middleware');
|
|
||||||
const checkAdmin = require('../middleware/permission-check').checkAdmin;
|
|
||||||
|
|
||||||
// HTTP status codes by name
|
// HTTP status codes by name
|
||||||
const codes = require('./http-codes');
|
const codes = require('./http-codes');
|
||||||
|
|
||||||
|
@ -25,7 +22,7 @@ const authenticate = express.Router();
|
||||||
// routes **********************
|
// routes **********************
|
||||||
authenticate.route('/')
|
authenticate.route('/')
|
||||||
.post((req, res, next) => {
|
.post((req, res, next) => {
|
||||||
authCheck(req.body.username, req.body.password, res)
|
authCheck(req.body.username, req.body.password)
|
||||||
.then((user) => {
|
.then((user) => {
|
||||||
if (user) {
|
if (user) {
|
||||||
// authentication successful
|
// authentication successful
|
||||||
|
@ -44,7 +41,7 @@ authenticate.route('/')
|
||||||
routerHandling.httpMethodNotAllowed
|
routerHandling.httpMethodNotAllowed
|
||||||
);
|
);
|
||||||
|
|
||||||
let authCheck = (username, password, res) => {
|
let authCheck = (username, password) => {
|
||||||
const deferred = Q.defer();
|
const deferred = Q.defer();
|
||||||
|
|
||||||
AppUserModel.findOne({username: username}, (err, user) => {
|
AppUserModel.findOne({username: username}, (err, user) => {
|
||||||
|
@ -52,15 +49,11 @@ let authCheck = (username, password, res) => {
|
||||||
|
|
||||||
const diff = 3 * 60 * 24; // time till expiration [minutes]
|
const diff = 3 * 60 * 24; // time till expiration [minutes]
|
||||||
|
|
||||||
if (user && !user.activated) {
|
if (user && bcrypt.compareSync(password, user.password)) {
|
||||||
res.status(codes.unauthorized).send('Account is not yet activated');
|
|
||||||
}
|
|
||||||
if (user && user.activated && bcrypt.compareSync(password, user.password)) {
|
|
||||||
// authentication successful
|
// authentication successful
|
||||||
deferred.resolve({
|
deferred.resolve({
|
||||||
_id: user._id,
|
_id: user._id,
|
||||||
username: user.username,
|
username: user.username,
|
||||||
permission: user.permission,
|
|
||||||
token: jwt.sign({sub: user._id}, config.secret, {expiresIn: diff * 60}),
|
token: jwt.sign({sub: user._id}, config.secret, {expiresIn: diff * 60}),
|
||||||
tokenExpireDate: new Date(Date.now().valueOf() + diff * 60000 - 1000)
|
tokenExpireDate: new Date(Date.now().valueOf() + diff * 60000 - 1000)
|
||||||
});
|
});
|
||||||
|
@ -73,57 +66,58 @@ let authCheck = (username, password, res) => {
|
||||||
return deferred.promise;
|
return deferred.promise;
|
||||||
};
|
};
|
||||||
|
|
||||||
// ******************************** SIGNUP ************************
|
|
||||||
|
|
||||||
authenticate.route('/signup')
|
//******************************** SIGNUP ************************
|
||||||
.post((req, res, next) => {
|
//
|
||||||
create(req.body)
|
// authenticate.route('/signup')
|
||||||
.then(() => {
|
// .post((req, res, next) => {
|
||||||
res.sendStatus(200);
|
// create(req.body)
|
||||||
})
|
// .then(() => {
|
||||||
.catch((err) => {
|
// res.sendStatus(200);
|
||||||
res.status(400).send(err);
|
// })
|
||||||
});
|
// .catch((err) => {
|
||||||
})
|
// res.status(400).send(err);
|
||||||
|
// });
|
||||||
.all(
|
// })
|
||||||
routerHandling.httpMethodNotAllowed
|
//
|
||||||
);
|
// .all(
|
||||||
|
// routerHandling.httpMethodNotAllowed
|
||||||
let create = (userParam) => {
|
// );
|
||||||
const deferred = Q.defer();
|
//
|
||||||
|
// let create = (userParam) => {
|
||||||
// validation
|
// const deferred = Q.defer();
|
||||||
AppUserModel.findOne(
|
//
|
||||||
{username: userParam.username},
|
// // validation
|
||||||
(err, user) => {
|
// AppUserModel.findOne(
|
||||||
if (err) deferred.reject(err.name + ': ' + err.message);
|
// {username: userParam.username},
|
||||||
|
// (err, user) => {
|
||||||
if (user) {
|
// if (err) deferred.reject(err.name + ': ' + err.message);
|
||||||
// username already exists
|
//
|
||||||
deferred.reject('Username "' + userParam.username + '" is already taken');
|
// if (user) {
|
||||||
} else {
|
// // username already exists
|
||||||
createUser();
|
// deferred.reject('Username "' + userParam.username + '" is already taken');
|
||||||
}
|
// } else {
|
||||||
});
|
// createUser();
|
||||||
|
// }
|
||||||
let createUser = () => {
|
// });
|
||||||
// set user object to userParam without the cleartext password
|
//
|
||||||
const user = _.omit(userParam, 'password');
|
// let createUser = () => {
|
||||||
|
// // set user object to userParam without the cleartext password
|
||||||
// add hashed password to user object
|
// const user = _.omit(userParam, 'password');
|
||||||
user.password = bcrypt.hashSync(userParam.password, 10);
|
//
|
||||||
|
// // add hashed password to user object
|
||||||
const newUser = new AppUserModel(user);
|
// user.password = bcrypt.hashSync(userParam.password, 10);
|
||||||
newUser.save((err, doc) => {
|
//
|
||||||
if (err) deferred.reject(err.name + ': ' + err.message);
|
// const newUser = new AppUserModel(user);
|
||||||
|
// newUser.save((err, doc) => {
|
||||||
deferred.resolve();
|
// if (err) deferred.reject(err.name + ': ' + err.message);
|
||||||
});
|
//
|
||||||
};
|
// deferred.resolve();
|
||||||
|
// });
|
||||||
return deferred.promise;
|
// };
|
||||||
};
|
//
|
||||||
|
// return deferred.promise;
|
||||||
|
// };
|
||||||
|
|
||||||
|
|
||||||
authenticate.use(routerHandling.emptyResponse);
|
authenticate.use(routerHandling.emptyResponse);
|
||||||
|
|
|
@ -187,7 +187,7 @@ users.route('/:id')
|
||||||
return; // prevent node to process this function further after next() has finished.
|
return; // prevent node to process this function further after next() has finished.
|
||||||
}
|
}
|
||||||
// main difference of PUT and PATCH is that PUT expects all data in request: checked by using the schema
|
// main difference of PUT and PATCH is that PUT expects all data in request: checked by using the schema
|
||||||
var user = new UserModel(req.body);
|
var video = new UserModel(req.body);
|
||||||
UserModel.findById(req.params.id, req.body, {new: true}, function (err, item) {
|
UserModel.findById(req.params.id, req.body, {new: true}, function (err, item) {
|
||||||
// with parameter {new: true} the TweetNModel will return the new and changed object from the DB and not the old one.
|
// with parameter {new: true} the TweetNModel will return the new and changed object from the DB and not the old one.
|
||||||
if (err) {
|
if (err) {
|
||||||
|
@ -200,7 +200,7 @@ users.route('/:id')
|
||||||
return next(err);
|
return next(err);
|
||||||
}
|
}
|
||||||
// optional task 3b: check that version is still accurate
|
// optional task 3b: check that version is still accurate
|
||||||
else if (user.__v !== item.__v) {
|
else if (video.__v !== item.__v) {
|
||||||
err = new Error("version outdated. Meanwhile update on item happened. Please GET resource again")
|
err = new Error("version outdated. Meanwhile update on item happened. Please GET resource again")
|
||||||
err.status = codes.conflict;
|
err.status = codes.conflict;
|
||||||
return next(err);
|
return next(err);
|
||||||
|
@ -209,7 +209,7 @@ users.route('/:id')
|
||||||
for (var field in UserModel.schema.paths) {
|
for (var field in UserModel.schema.paths) {
|
||||||
if ((field !== '_id') && (field !== '__v')) {
|
if ((field !== '_id') && (field !== '__v')) {
|
||||||
// this includes undefined. is important to reset attributes that are missing in req.body
|
// this includes undefined. is important to reset attributes that are missing in req.body
|
||||||
item.set(field, user[field]);
|
item.set(field, video[field]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,6 @@ const signatureCronJob = require('./cron-job/update-signatures');
|
||||||
|
|
||||||
// router modules
|
// router modules
|
||||||
const authenticateRouter = require('./routes/authenticate');
|
const authenticateRouter = require('./routes/authenticate');
|
||||||
const accountRouter = require('./routes/account');
|
|
||||||
const overviewRouter = require('./routes/overview');
|
const overviewRouter = require('./routes/overview');
|
||||||
const userRouter = require('./routes/users');
|
const userRouter = require('./routes/users');
|
||||||
const squadRouter = require('./routes/squads');
|
const squadRouter = require('./routes/squads');
|
||||||
|
@ -74,7 +73,6 @@ app.use(urls.ranks, rankRouter);
|
||||||
app.use(urls.decorations, decorationRouter);
|
app.use(urls.decorations, decorationRouter);
|
||||||
app.use(urls.awards, apiAuthenticationMiddleware, checkHl, awardingRouter);
|
app.use(urls.awards, apiAuthenticationMiddleware, checkHl, awardingRouter);
|
||||||
app.use(urls.command, apiAuthenticationMiddleware, checkAdmin, commandRouter);
|
app.use(urls.command, apiAuthenticationMiddleware, checkAdmin, commandRouter);
|
||||||
app.use(urls.account, apiAuthenticationMiddleware, checkAdmin, accountRouter);
|
|
||||||
|
|
||||||
// send index.html on all different paths
|
// send index.html on all different paths
|
||||||
app.use(function (req, res) {
|
app.use(function (req, res) {
|
||||||
|
|
|
@ -1,34 +0,0 @@
|
||||||
.overview {
|
|
||||||
position: fixed;
|
|
||||||
overflow-y: scroll;
|
|
||||||
overflow-x: hidden;
|
|
||||||
bottom: 20px;
|
|
||||||
width: 100%;
|
|
||||||
padding-left: 50px;
|
|
||||||
padding-top: 190px;
|
|
||||||
margin-left: 10px;
|
|
||||||
height: 100vh;
|
|
||||||
}
|
|
||||||
|
|
||||||
.trash {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.table {
|
|
||||||
overflow-wrap: break-word;
|
|
||||||
table-layout: fixed;
|
|
||||||
}
|
|
||||||
|
|
||||||
.table-container {
|
|
||||||
margin-top: 10px;
|
|
||||||
overflow-x: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.table-head {
|
|
||||||
background: #222222;
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cell-outline {
|
|
||||||
outline: 1px solid #D4D4D4;
|
|
||||||
}
|
|
|
@ -1,71 +0,0 @@
|
||||||
<div class="overview">
|
|
||||||
|
|
||||||
<h2>Admin Panel</h2>
|
|
||||||
|
|
||||||
<span *ngIf="showSuccessLabel"
|
|
||||||
class="label label-success label-small"
|
|
||||||
style="margin-left: inherit">
|
|
||||||
Erfolgreich gespeichert
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<div class="pull-left" style="margin-top:20px;">
|
|
||||||
<div class="table-container" style="width: 75%; min-width: 500px">
|
|
||||||
<table class="table table-hover">
|
|
||||||
<thead>
|
|
||||||
<tr class="table-head">
|
|
||||||
<th class="col-sm-1" style="border-radius: 10px 0 0 0;">Username</th>
|
|
||||||
<th class="col-sm-1">Activated</th>
|
|
||||||
<th class="col-sm-1">Secret</th>
|
|
||||||
<th class="col-sm-1">Fraktion/ Squad</th>
|
|
||||||
<th class="col-sm-1">Permission</th>
|
|
||||||
<th class="col-sm-1 text-center" style="border-radius: 0 10px 0 0;"></th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody *ngFor="let user of users$ | async">
|
|
||||||
<tr class="cell-outline">
|
|
||||||
<td>
|
|
||||||
{{user.username}}
|
|
||||||
</td>
|
|
||||||
<td style="font-weight: bold">
|
|
||||||
<select id="activated" name="activated" class="form-control btn dropdown-toggle"
|
|
||||||
[(ngModel)]="user.activated" (change)="updateAppUser(user)">
|
|
||||||
<option value="true">activated</option>
|
|
||||||
<option value="false">deactivated</option>
|
|
||||||
</select>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
{{user.secret}}
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<select class="form-control"
|
|
||||||
name="squad"
|
|
||||||
id="squad"
|
|
||||||
[(ngModel)]="user.squad"
|
|
||||||
[compareWith]="equals"
|
|
||||||
(change)="updateAppUser(user)">
|
|
||||||
<option [value]="0">Ohne Fraktion/ Squad</option>
|
|
||||||
<option *ngFor="let squad of squads" [ngValue]="squad">
|
|
||||||
{{squad.fraction == 'BLUFOR'? 'NATO' : 'CSAT'}}: {{squad.name}}
|
|
||||||
</option>
|
|
||||||
</select>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<select id="permission" name="permission" class="form-control btn dropdown-toggle"
|
|
||||||
[(ngModel)]="user.permission" (change)="updateAppUser(user)">
|
|
||||||
<option value="0">User</option>
|
|
||||||
<option value="1">SQL</option>
|
|
||||||
<option value="2">HL</option>
|
|
||||||
<option value="3">MT</option>
|
|
||||||
<option value="4">Admin</option>
|
|
||||||
</select>
|
|
||||||
</td>
|
|
||||||
<td class="text-center">
|
|
||||||
<span class="glyphicon glyphicon-trash trash" title="Löschen" (click)="deleteUser(user)"></span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
|
@ -1,70 +0,0 @@
|
||||||
import {Component} from "@angular/core";
|
|
||||||
import {AppUser, Squad} from "../models/model-interfaces";
|
|
||||||
import {Observable} from "rxjs/Observable";
|
|
||||||
import {AppUserService} from "../services/app-user-service/app-user.service";
|
|
||||||
import {SquadService} from "../services/squad-service/squad.service";
|
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'admin-panel',
|
|
||||||
templateUrl: './admin.component.html',
|
|
||||||
styleUrls: ['./admin.component.css']
|
|
||||||
})
|
|
||||||
export class AdminComponent {
|
|
||||||
|
|
||||||
users$: Observable<AppUser[]>;
|
|
||||||
|
|
||||||
squads: Squad[] = [];
|
|
||||||
|
|
||||||
showSuccessLabel = false;
|
|
||||||
|
|
||||||
constructor(private appUserService: AppUserService,
|
|
||||||
private squadService: SquadService) {
|
|
||||||
}
|
|
||||||
|
|
||||||
ngOnInit() {
|
|
||||||
this.users$ = this.appUserService.getUsers();
|
|
||||||
this.squadService.findSquads().subscribe(squads => {
|
|
||||||
this.squads = squads;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
updateAppUser(user) {
|
|
||||||
let updateObject = {
|
|
||||||
_id: user._id,
|
|
||||||
squad: user.squad,
|
|
||||||
activated: user.activated,
|
|
||||||
permission: user.permission
|
|
||||||
};
|
|
||||||
|
|
||||||
if (updateObject.squad === "0") {
|
|
||||||
updateObject.squad = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.appUserService.updateUser(updateObject)
|
|
||||||
.subscribe(user => {
|
|
||||||
this.showSuccessLabel = true;
|
|
||||||
setTimeout(() => {
|
|
||||||
this.showSuccessLabel = false;
|
|
||||||
}, 2000)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
deleteUser(user) {
|
|
||||||
if (confirm('Soll der Nutzer "' + user.username + '" wirklich gelöscht werden?')) {
|
|
||||||
this.appUserService.deleteUser(user)
|
|
||||||
.subscribe((res) => {
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* compare ngValue with ngModel to assign selected element
|
|
||||||
*/
|
|
||||||
equals(o1: Squad , o2: Squad) {
|
|
||||||
if (o1 && o2) {
|
|
||||||
return o1._id === o2._id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -21,41 +21,23 @@
|
||||||
<li routerLinkActive="active">
|
<li routerLinkActive="active">
|
||||||
<a routerLink='/cc-overview' class="link">Armeeübersicht</a>
|
<a routerLink='/cc-overview' class="link">Armeeübersicht</a>
|
||||||
</li>
|
</li>
|
||||||
<li *ngIf="loginService.hasPermission(2)" routerLinkActive="active">
|
<li *ngIf="loginService.isLoggedIn()" routerLinkActive="active">
|
||||||
<a routerLink='/cc-users' class="link">Teilnehmer</a>
|
<a routerLink='/cc-users' class="link">Teilnehmer</a>
|
||||||
</li>
|
</li>
|
||||||
<li *ngIf="loginService.hasPermission(2)" routerLinkActive="active">
|
<li *ngIf="loginService.isLoggedIn()" routerLinkActive="active">
|
||||||
<a routerLink='/cc-squads' class="link">Squads</a>
|
<a routerLink='/cc-squads' class="link">Squads</a>
|
||||||
</li>
|
</li>
|
||||||
<li *ngIf="loginService.hasPermission(2)" routerLinkActive="active">
|
<li *ngIf="loginService.isLoggedIn()" routerLinkActive="active">
|
||||||
<a routerLink='/cc-decorations' class="link">Auszeichnungen</a>
|
<a routerLink='/cc-decorations' class="link">Auszeichnungen</a>
|
||||||
</li>
|
</li>
|
||||||
<li *ngIf="loginService.hasPermission(2)" routerLinkActive="active">
|
<li *ngIf="loginService.isLoggedIn()" routerLinkActive="active">
|
||||||
<a routerLink='/cc-ranks' class="link">Ränge</a>
|
<a routerLink='/cc-ranks' class="link">Ränge</a>
|
||||||
</li>
|
</li>
|
||||||
<li *ngIf="loginService.hasPermission(1) && !loginService.hasPermission(2)" class="dropdown">
|
|
||||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
|
|
||||||
aria-expanded="false">
|
|
||||||
Beantragen
|
|
||||||
<span class="caret"></span>
|
|
||||||
</a>
|
|
||||||
<ul class="dropdown-menu">
|
|
||||||
<li>
|
|
||||||
<a [routerLink]="['/request-promotion']">Beförderung</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a [routerLink]="['/request-award']">Orden/ Auszeichnung</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<ul class="nav navbar-nav" style="float: right">
|
<ul class="nav navbar-nav" style="float: right">
|
||||||
<li *ngIf="loginService.hasPermission(4)" routerLinkActive="active">
|
|
||||||
<a routerLink='/admin-panel' class="link">Admin Panel</a>
|
|
||||||
</li>
|
|
||||||
<li *ngIf="authEnabled" class="link" style="cursor: pointer">
|
<li *ngIf="authEnabled" class="link" style="cursor: pointer">
|
||||||
<a *ngIf="loginService.isLoggedIn()" (click)="logout()">Abmelden</a>
|
<a *ngIf="loginService.isLoggedIn()" (click)="logout()" >Abmelden</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -3,11 +3,9 @@ export class AppConfig {
|
||||||
|
|
||||||
public readonly apiUrl = '';
|
public readonly apiUrl = '';
|
||||||
|
|
||||||
public readonly apiAppUserPath = '/account/';
|
|
||||||
public readonly apiAwardPath = '/awardings/';
|
public readonly apiAwardPath = '/awardings/';
|
||||||
public readonly apiDecorationPath = '/decorations/';
|
public readonly apiDecorationPath = '/decorations/';
|
||||||
public readonly apiAuthenticationPath = '/authenticate';
|
public readonly apiAuthenticationPath = '/authenticate';
|
||||||
public readonly apiSignupPath = '/authenticate/signup';
|
|
||||||
public readonly apiRankPath = '/ranks/';
|
public readonly apiRankPath = '/ranks/';
|
||||||
public readonly apiSquadPath = '/squads/';
|
public readonly apiSquadPath = '/squads/';
|
||||||
public readonly apiUserPath = '/users/';
|
public readonly apiUserPath = '/users/';
|
||||||
|
|
|
@ -22,25 +22,19 @@ import {RankStore} from "./services/stores/rank.store";
|
||||||
import {RankService} from "./services/rank-service/rank.service";
|
import {RankService} from "./services/rank-service/rank.service";
|
||||||
import {DecorationItemComponent} from "./decorations/decoration-list/decoration-item.component";
|
import {DecorationItemComponent} from "./decorations/decoration-list/decoration-item.component";
|
||||||
import {AppConfig} from "./app.config";
|
import {AppConfig} from "./app.config";
|
||||||
import {LoginGuardAdmin, LoginGuardHL, LoginGuardSQL} from "./login/login.guard";
|
import {LoginGuard} from "./login/login.guard";
|
||||||
import {AwardingService} from "./services/awarding-service/awarding.service";
|
import {AwardingService} from "./services/awarding-service/awarding.service";
|
||||||
import {HttpClient} from "./services/http-client";
|
import {HttpClient} from "./services/http-client";
|
||||||
import {ArmyService} from "./services/army-service/army.service";
|
import {ArmyService} from "./services/army-service/army.service";
|
||||||
import { ClipboardModule } from 'ngx-clipboard';
|
import { ClipboardModule } from 'ngx-clipboard';
|
||||||
import {AppUserService} from "./services/app-user-service/app-user.service";
|
|
||||||
import {AppUserStore} from "./services/stores/app-user.store";
|
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [BrowserModule, FormsModule, ReactiveFormsModule, appRouting, HttpModule, ClipboardModule],
|
imports: [BrowserModule, FormsModule, ReactiveFormsModule, appRouting, HttpModule, ClipboardModule],
|
||||||
providers: [
|
providers: [
|
||||||
HttpClient,
|
HttpClient,
|
||||||
LoginService,
|
LoginService,
|
||||||
LoginGuardSQL,
|
LoginGuard,
|
||||||
LoginGuardHL,
|
|
||||||
LoginGuardAdmin,
|
|
||||||
ArmyService,
|
ArmyService,
|
||||||
AppUserService,
|
|
||||||
AppUserStore,
|
|
||||||
UserService,
|
UserService,
|
||||||
UserStore,
|
UserStore,
|
||||||
SquadService,
|
SquadService,
|
||||||
|
|
|
@ -1,14 +1,12 @@
|
||||||
import {Routes, RouterModule} from '@angular/router';
|
import {Routes, RouterModule} from '@angular/router';
|
||||||
import {LoginComponent} from './login/index';
|
import {LoginComponent} from './login/index';
|
||||||
import {NotFoundComponent} from './not-found/not-found.component';
|
import {NotFoundComponent} from './not-found/not-found.component';
|
||||||
import {LoginGuardAdmin, LoginGuardHL} from './login/login.guard';
|
import {LoginGuard} from './login/login.guard';
|
||||||
import {usersRoutes, usersRoutingComponents} from "./users/users.routing";
|
import {usersRoutes, usersRoutingComponents} from "./users/users.routing";
|
||||||
import {squadsRoutes, squadsRoutingComponents} from "./squads/squads.routing";
|
import {squadsRoutes, squadsRoutingComponents} from "./squads/squads.routing";
|
||||||
import {decorationsRoutes, decorationsRoutingComponents} from "./decorations/decoration.routing";
|
import {decorationsRoutes, decorationsRoutingComponents} from "./decorations/decoration.routing";
|
||||||
import {ranksRoutes, ranksRoutingComponents} from "./ranks/ranks.routing";
|
import {ranksRoutes, ranksRoutingComponents} from "./ranks/ranks.routing";
|
||||||
import {armyRoutes, armyRoutingComponents} from "./army/army.routing";
|
import {armyRoutes, armyRoutingComponents} from "./army/army.routing";
|
||||||
import {SignupComponent} from "./login/signup.component";
|
|
||||||
import {AdminComponent} from "./admin/admin.component";
|
|
||||||
|
|
||||||
|
|
||||||
export const appRoutes: Routes = [
|
export const appRoutes: Routes = [
|
||||||
|
@ -17,13 +15,10 @@ export const appRoutes: Routes = [
|
||||||
{path: '', redirectTo: '/cc-overview', pathMatch: 'full'},
|
{path: '', redirectTo: '/cc-overview', pathMatch: 'full'},
|
||||||
|
|
||||||
{path: 'login', component: LoginComponent},
|
{path: 'login', component: LoginComponent},
|
||||||
{path: 'signup', component: SignupComponent},
|
{path: 'cc-users', children: usersRoutes, canActivate: [LoginGuard]},
|
||||||
{path: 'cc-users', children: usersRoutes, canActivate: [LoginGuardHL]},
|
{path: 'cc-squads', children: squadsRoutes, canActivate: [LoginGuard]},
|
||||||
{path: 'cc-squads', children: squadsRoutes, canActivate: [LoginGuardHL]},
|
{path: 'cc-decorations', children: decorationsRoutes, canActivate: [LoginGuard]},
|
||||||
{path: 'cc-decorations', children: decorationsRoutes, canActivate: [LoginGuardHL]},
|
{path: 'cc-ranks', children: ranksRoutes, canActivate: [LoginGuard]},
|
||||||
{path: 'cc-ranks', children: ranksRoutes, canActivate: [LoginGuardHL]},
|
|
||||||
|
|
||||||
{path: 'admin-panel', component: AdminComponent, canActivate: [LoginGuardAdmin]},
|
|
||||||
|
|
||||||
/** Redirect Konfigurationen **/
|
/** Redirect Konfigurationen **/
|
||||||
{path: '404', component: NotFoundComponent},
|
{path: '404', component: NotFoundComponent},
|
||||||
|
@ -32,7 +27,7 @@ export const appRoutes: Routes = [
|
||||||
|
|
||||||
export const appRouting = RouterModule.forRoot(appRoutes);
|
export const appRouting = RouterModule.forRoot(appRoutes);
|
||||||
|
|
||||||
export const routingComponents = [LoginComponent, SignupComponent, AdminComponent, ...armyRoutingComponents , NotFoundComponent, ...usersRoutingComponents,
|
export const routingComponents = [LoginComponent, ...armyRoutingComponents , NotFoundComponent, ...usersRoutingComponents,
|
||||||
...squadsRoutingComponents, ...decorationsRoutingComponents, ...ranksRoutingComponents];
|
...squadsRoutingComponents, ...decorationsRoutingComponents, ...ranksRoutingComponents];
|
||||||
|
|
||||||
export const routingProviders = [LoginGuardHL];
|
export const routingProviders = [LoginGuard];
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.form-signin .form-signin-heading, .form-signin .checkbox, #inputEmail {
|
.form-signin .form-signin-heading, .form-signin .checkbox {
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
</button>
|
</button>
|
||||||
<span *ngIf="showErrorLabel"
|
<span *ngIf="showErrorLabel"
|
||||||
class="center-block label label-danger" style="font-size: medium; padding: 2px; margin-top: 2px">
|
class="center-block label label-danger" style="font-size: medium; padding: 2px; margin-top: 2px">
|
||||||
{{error}}
|
Login fehlgeschlagen
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -13,8 +13,6 @@ export class LoginComponent implements OnInit {
|
||||||
|
|
||||||
showErrorLabel = false;
|
showErrorLabel = false;
|
||||||
|
|
||||||
error: string;
|
|
||||||
|
|
||||||
loading = false;
|
loading = false;
|
||||||
|
|
||||||
returnUrl: string;
|
returnUrl: string;
|
||||||
|
@ -27,8 +25,8 @@ export class LoginComponent implements OnInit {
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
// reset login status
|
// reset login status
|
||||||
this.loginService.logout();
|
this.loginService.logout();
|
||||||
// redirect on success
|
// redirect to user overview on success
|
||||||
this.returnUrl = '/cc-overview'
|
this.returnUrl = '/cc-users'
|
||||||
}
|
}
|
||||||
|
|
||||||
login(username: string, password: string) {
|
login(username: string, password: string) {
|
||||||
|
@ -40,8 +38,6 @@ export class LoginComponent implements OnInit {
|
||||||
this.router.navigate([this.returnUrl]);
|
this.router.navigate([this.returnUrl]);
|
||||||
},
|
},
|
||||||
error => {
|
error => {
|
||||||
console.log(error)
|
|
||||||
this.error = error._body;
|
|
||||||
this.showErrorLabel = true;
|
this.showErrorLabel = true;
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.showErrorLabel = false;
|
this.showErrorLabel = false;
|
||||||
|
|
|
@ -2,57 +2,14 @@ import { Injectable } from '@angular/core';
|
||||||
import { Router, CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
|
import { Router, CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class LoginGuardSQL implements CanActivate {
|
export class LoginGuard implements CanActivate {
|
||||||
|
|
||||||
constructor(private router: Router) { }
|
constructor(private router: Router) { }
|
||||||
|
|
||||||
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
|
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
|
||||||
if (localStorage.getItem('currentUser')) {
|
if (localStorage.getItem('currentUser')) {
|
||||||
let currentUser = JSON.parse(localStorage.getItem('currentUser'));
|
// logged in so return true
|
||||||
if (currentUser.permission === 1) {
|
return true;
|
||||||
// logged and correct permission so return true
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// not logged in so redirect to login page with the return url
|
|
||||||
this.router.navigate(['/login'], { queryParams: { returnUrl: state.url }});
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
export class LoginGuardHL implements CanActivate {
|
|
||||||
|
|
||||||
constructor(private router: Router) { }
|
|
||||||
|
|
||||||
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
|
|
||||||
if (localStorage.getItem('currentUser')) {
|
|
||||||
let currentUser = JSON.parse(localStorage.getItem('currentUser'));
|
|
||||||
if (currentUser.permission >= 2) {
|
|
||||||
// logged and correct permission so return true
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// not logged in so redirect to login page with the return url
|
|
||||||
this.router.navigate(['/login'], { queryParams: { returnUrl: state.url }});
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
export class LoginGuardAdmin implements CanActivate {
|
|
||||||
|
|
||||||
constructor(private router: Router) { }
|
|
||||||
|
|
||||||
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
|
|
||||||
if (localStorage.getItem('currentUser')) {
|
|
||||||
let currentUser = JSON.parse(localStorage.getItem('currentUser'));
|
|
||||||
if (currentUser.permission === 4) {
|
|
||||||
// logged and correct permission so return true
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// not logged in so redirect to login page with the return url
|
// not logged in so redirect to login page with the return url
|
||||||
|
|
|
@ -1,39 +0,0 @@
|
||||||
<form class="form-signin" (ngSubmit)="login(userName.value, password.value, secret.value)">
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<h2 style="text-align: center;" class="form-signin-heading">Registrieren</h2>
|
|
||||||
|
|
||||||
<p>Dieses Formular nur ausfüllen wenn du einer <b>HL</b> angehörst oder <b>SQL</b> bist. Dabei den Nutzernamen aus dem OPT Forum verwenden!
|
|
||||||
Im Forum eine Nachricht an <a href="https://opt-dev.de/dashboard/index.php?conversation-add/&userID=9" target="_blank">HardiReady</a>
|
|
||||||
senden, in welcher der 'geheime Text' drin steht, den du bei der Registrierung nutzt.<br>
|
|
||||||
Dabei kann es sich um irgend eine willkürliche Zeichenfolge oder einen Satz handeln - dient nur dem Abgleich.
|
|
||||||
Anschließend wird dein Account aktiviert und du wirst darüber per PN informiert.</p>
|
|
||||||
|
|
||||||
<label for="inputEmail" class="sr-only">Benutzername</label>
|
|
||||||
<input #userName id="inputEmail" class="form-control" placeholder="Benutzername" required="" autofocus="">
|
|
||||||
|
|
||||||
<label for="inputPassword" class="sr-only">Passwort</label>
|
|
||||||
<input #password type="password" id="inputPassword" class="form-control" placeholder="Passwort" required="">
|
|
||||||
|
|
||||||
<label for="inputSecret" class="sr-only">Secret</label>
|
|
||||||
<input #secret type="text" id="inputSecret" class="form-control" placeholder="Geheimer Text für PN Abgleich"
|
|
||||||
required="">
|
|
||||||
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<button type="submit" class="btn btn-lg btn-block btn-primary">
|
|
||||||
<span *ngIf="!loading">Registrieren</span>
|
|
||||||
<span *ngIf="loading" class="glyphicon glyphicon-refresh glyphicon-refresh-animate"></span>
|
|
||||||
</button>
|
|
||||||
<span *ngIf="showErrorLabel"
|
|
||||||
class="center-block label label-danger" style="font-size: medium; padding: 2px; margin-top: 2px">
|
|
||||||
Login fehlgeschlagen
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
</form>
|
|
||||||
|
|
|
@ -1,50 +0,0 @@
|
||||||
import {Component, OnInit} from "@angular/core";
|
|
||||||
import {ActivatedRoute, Router} from "@angular/router";
|
|
||||||
import {LoginService} from "../services/login-service/login-service";
|
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
moduleId: module.id,
|
|
||||||
templateUrl: './signup.component.html',
|
|
||||||
styleUrls: ['./login.component.css']
|
|
||||||
})
|
|
||||||
|
|
||||||
export class SignupComponent implements OnInit {
|
|
||||||
|
|
||||||
showErrorLabel = false;
|
|
||||||
|
|
||||||
loading = false;
|
|
||||||
|
|
||||||
returnUrl: string;
|
|
||||||
|
|
||||||
constructor(private route: ActivatedRoute,
|
|
||||||
private router: Router,
|
|
||||||
private loginService: LoginService) {
|
|
||||||
}
|
|
||||||
|
|
||||||
ngOnInit() {
|
|
||||||
// reset login status
|
|
||||||
this.loginService.logout();
|
|
||||||
// redirect on success
|
|
||||||
this.returnUrl = '/cc-overview'
|
|
||||||
}
|
|
||||||
|
|
||||||
login(username: string, password: string, secret: string) {
|
|
||||||
if (username.length > 0 && password.length > 0 && secret.length > 0) {
|
|
||||||
this.loading = true;
|
|
||||||
this.loginService.signUp(username, password, secret)
|
|
||||||
.subscribe(
|
|
||||||
data => {
|
|
||||||
console.log(data)
|
|
||||||
//this.router.navigate([this.returnUrl]);
|
|
||||||
},
|
|
||||||
error => {
|
|
||||||
this.showErrorLabel = true;
|
|
||||||
setTimeout(() => {
|
|
||||||
this.showErrorLabel = false;
|
|
||||||
}, 4000);
|
|
||||||
this.loading = false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,12 +1,3 @@
|
||||||
export interface AppUser {
|
|
||||||
_id?: string;
|
|
||||||
username?: string;
|
|
||||||
squad?: Squad;
|
|
||||||
secret?: string;
|
|
||||||
activated: boolean;
|
|
||||||
permission: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface User {
|
export interface User {
|
||||||
_id?: string;
|
_id?: string;
|
||||||
boardUserId?: number;
|
boardUserId?: number;
|
||||||
|
@ -77,3 +68,59 @@ export interface Army {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface Tag {
|
||||||
|
label: string;
|
||||||
|
}
|
||||||
|
export interface Assignee {
|
||||||
|
name?: string;
|
||||||
|
email?: string;
|
||||||
|
}
|
||||||
|
export interface Task {
|
||||||
|
id?: number;
|
||||||
|
title?: string;
|
||||||
|
description?: string;
|
||||||
|
tags?: Tag[];
|
||||||
|
favorite?: boolean;
|
||||||
|
state?: string;
|
||||||
|
assignee?: Assignee;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const states = ['BACKLOG', 'IN_PROGRESS', 'TEST', 'COMPLETED'];
|
||||||
|
|
||||||
|
export function createInitialTask(): Task {
|
||||||
|
return {
|
||||||
|
assignee: {},
|
||||||
|
tags: [],
|
||||||
|
state: states[0]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export const stateGroups = [
|
||||||
|
{
|
||||||
|
label: 'Planung',
|
||||||
|
states: ['BACKLOG']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Entwicklung',
|
||||||
|
states: ['IN_PROGRESS', 'TEST']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'In Produktion',
|
||||||
|
states: ['COMPLETED']
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
export const stateTexts = {
|
||||||
|
'BACKLOG': 'Backlog',
|
||||||
|
'IN_PROGRESS': 'In Bearbeitung',
|
||||||
|
'TEST': 'Im Test',
|
||||||
|
'COMPLETED': 'Abgeschlossen'
|
||||||
|
};
|
||||||
|
|
||||||
|
export const statesAsObjects = [{name: 'BACKLOG', text: 'Backlog'},
|
||||||
|
{name: 'IN_PROGRESS', text: 'In Bearbeitung'},
|
||||||
|
{name: 'TEST', text: 'Test'},
|
||||||
|
{name: 'COMPLETED', text: 'Abgeschlossen'}];
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,48 +0,0 @@
|
||||||
import {Injectable} from "@angular/core";
|
|
||||||
import {AppUser, User} from "../../models/model-interfaces";
|
|
||||||
import {URLSearchParams} from "@angular/http";
|
|
||||||
import {Observable} from "rxjs/Observable";
|
|
||||||
import {ADD, EDIT, LOAD, REMOVE} from "../stores/user.store";
|
|
||||||
import {AppConfig} from "../../app.config";
|
|
||||||
import {HttpClient} from "../http-client";
|
|
||||||
import {AppUserStore} from "../stores/app-user.store";
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
export class AppUserService {
|
|
||||||
|
|
||||||
users$: Observable<AppUser[]>;
|
|
||||||
|
|
||||||
constructor(private http: HttpClient,
|
|
||||||
private appUserStore: AppUserStore,
|
|
||||||
private config: AppConfig) {
|
|
||||||
this.users$ = appUserStore.items$;
|
|
||||||
}
|
|
||||||
|
|
||||||
getUsers() {
|
|
||||||
this.http.get(this.config.apiUrl + this.config.apiAppUserPath)
|
|
||||||
.map(res => res.json())
|
|
||||||
.do((users) => {
|
|
||||||
this.appUserStore.dispatch({type: LOAD, data: users});
|
|
||||||
}).subscribe(_ => {
|
|
||||||
});
|
|
||||||
|
|
||||||
return this.users$;
|
|
||||||
}
|
|
||||||
|
|
||||||
updateUser(user: AppUser) {
|
|
||||||
return this.http.patch(this.config.apiUrl + this.config.apiAppUserPath + user._id, user)
|
|
||||||
.map(res => res.json())
|
|
||||||
.do(savedUser => {
|
|
||||||
const action = {type: EDIT, data: savedUser};
|
|
||||||
this.appUserStore.dispatch(action);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
deleteUser(user) {
|
|
||||||
return this.http.delete(this.config.apiUrl + this.config.apiAppUserPath + user._id)
|
|
||||||
.do(res => {
|
|
||||||
this.appUserStore.dispatch({type: REMOVE, data: user});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -24,17 +24,6 @@ export class LoginService {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
signUp(username: string, password: string, secret: string) {
|
|
||||||
return this.http.post(this.config.apiUrl + this.config.apiSignupPath, {username: username, password: password, secret: secret})
|
|
||||||
.map((response: Response) => {
|
|
||||||
// login successful if there's a jwt token in the response
|
|
||||||
let user = response.json();
|
|
||||||
if (user) {
|
|
||||||
//TODO
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
logout() {
|
logout() {
|
||||||
// remove user from local storage
|
// remove user from local storage
|
||||||
localStorage.removeItem('currentUser');
|
localStorage.removeItem('currentUser');
|
||||||
|
@ -44,9 +33,4 @@ export class LoginService {
|
||||||
return !this.authEnabled || localStorage.getItem('currentUser') != null;
|
return !this.authEnabled || localStorage.getItem('currentUser') != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
hasPermission(level : number) {
|
|
||||||
let currentUser = JSON.parse(localStorage.getItem('currentUser'));
|
|
||||||
return this.isLoggedIn() && currentUser.permission >= level;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,41 +0,0 @@
|
||||||
import {BehaviorSubject} from "rxjs/BehaviorSubject";
|
|
||||||
import {AppUser, User} from "../../models/model-interfaces";
|
|
||||||
|
|
||||||
export const LOAD = 'LOAD';
|
|
||||||
export const ADD = 'ADD';
|
|
||||||
export const EDIT = 'EDIT';
|
|
||||||
export const REMOVE = 'REMOVE';
|
|
||||||
|
|
||||||
export class AppUserStore {
|
|
||||||
|
|
||||||
private appUsers: AppUser[] = [];
|
|
||||||
|
|
||||||
items$ = new BehaviorSubject<AppUser[]>([]);
|
|
||||||
|
|
||||||
dispatch(action) {
|
|
||||||
this.appUsers = this._reduce(this.appUsers, action);
|
|
||||||
this.items$.next(this.appUsers);
|
|
||||||
}
|
|
||||||
|
|
||||||
_reduce(users: AppUser[], action) {
|
|
||||||
switch (action.type) {
|
|
||||||
case LOAD:
|
|
||||||
return [...action.data];
|
|
||||||
case ADD:
|
|
||||||
return [...users, action.data];
|
|
||||||
case EDIT:
|
|
||||||
return users.map(user => {
|
|
||||||
const editedUser = action.data;
|
|
||||||
if (user._id !== editedUser._id) {
|
|
||||||
return user;
|
|
||||||
}
|
|
||||||
return editedUser;
|
|
||||||
});
|
|
||||||
case REMOVE:
|
|
||||||
return users.filter(user => user._id !== action.data._id);
|
|
||||||
default:
|
|
||||||
return users;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
Binary file not shown.
Before Width: | Height: | Size: 7.7 KiB After Width: | Height: | Size: 7.6 KiB |
Loading…
Reference in New Issue