diff --git a/src/app/components/login/login.component.ts b/src/app/components/login/login.component.ts
index a592302..0665ee0 100644
--- a/src/app/components/login/login.component.ts
+++ b/src/app/components/login/login.component.ts
@@ -40,6 +40,9 @@ export class LoginComponent implements OnInit {
}
login() {
+ if (this.loginPasswordInput === '') {
+ return;
+ }
this.loggingIn = true;
this.postsService.login(this.loginUsernameInput, this.loginPasswordInput).subscribe(res => {
this.loggingIn = false;
diff --git a/src/app/components/manage-role/manage-role.component.html b/src/app/components/manage-role/manage-role.component.html
new file mode 100644
index 0000000..b3e8de9
--- /dev/null
+++ b/src/app/components/manage-role/manage-role.component.html
@@ -0,0 +1,19 @@
+
Manage role - {{role.name}}
+
+
+
+
+ {{permissionToLabel[permission] ? permissionToLabel[permission] : permission}}
+
+
+ Yes
+ No
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/app/components/manage-role/manage-role.component.scss b/src/app/components/manage-role/manage-role.component.scss
new file mode 100644
index 0000000..167abd6
--- /dev/null
+++ b/src/app/components/manage-role/manage-role.component.scss
@@ -0,0 +1,4 @@
+.mat-radio-button {
+ margin-right: 10px;
+ margin-top: 5px;
+}
\ No newline at end of file
diff --git a/src/app/components/manage-role/manage-role.component.spec.ts b/src/app/components/manage-role/manage-role.component.spec.ts
new file mode 100644
index 0000000..2e9579e
--- /dev/null
+++ b/src/app/components/manage-role/manage-role.component.spec.ts
@@ -0,0 +1,25 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { ManageRoleComponent } from './manage-role.component';
+
+describe('ManageRoleComponent', () => {
+ let component: ManageRoleComponent;
+ let fixture: ComponentFixture
;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ ManageRoleComponent ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(ManageRoleComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/app/components/manage-role/manage-role.component.ts b/src/app/components/manage-role/manage-role.component.ts
new file mode 100644
index 0000000..4e05e29
--- /dev/null
+++ b/src/app/components/manage-role/manage-role.component.ts
@@ -0,0 +1,61 @@
+import { Component, OnInit, Inject } from '@angular/core';
+import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
+import { PostsService } from 'app/posts.services';
+
+@Component({
+ selector: 'app-manage-role',
+ templateUrl: './manage-role.component.html',
+ styleUrls: ['./manage-role.component.scss']
+})
+export class ManageRoleComponent implements OnInit {
+
+ role = null;
+ available_permissions = null;
+ permissions = null;
+
+ permissionToLabel = {
+ 'filemanager': 'File manager',
+ 'settings': 'Settings access',
+ 'subscriptions': 'Subscriptions',
+ 'sharing': 'Share files',
+ 'advanced_download': 'Use advanced download mode',
+ 'downloads_manager': 'Use downloads manager'
+ }
+
+ constructor(public postsService: PostsService, private dialogRef: MatDialogRef,
+ @Inject(MAT_DIALOG_DATA) public data: any) {
+ if (this.data) {
+ this.role = this.data.role;
+ this.available_permissions = this.postsService.available_permissions;
+ this.parsePermissions();
+ }
+ }
+
+ ngOnInit(): void {
+ }
+
+ parsePermissions() {
+ this.permissions = {};
+ for (let i = 0; i < this.available_permissions.length; i++) {
+ const permission = this.available_permissions[i];
+ if (this.role.permissions.includes(permission)) {
+ this.permissions[permission] = 'yes';
+ } else {
+ this.permissions[permission] = 'no';
+ }
+ }
+ }
+
+ changeRolePermissions(change, permission) {
+ this.postsService.setRolePermission(this.role.name, permission, change.value).subscribe(res => {
+ if (res['success']) {
+
+ } else {
+ this.permissions[permission] = this.permissions[permission] === 'yes' ? 'no' : 'yes';
+ }
+ }, err => {
+ this.permissions[permission] = this.permissions[permission] === 'yes' ? 'no' : 'yes';
+ });
+ }
+
+}
diff --git a/src/app/components/manage-user/manage-user.component.html b/src/app/components/manage-user/manage-user.component.html
new file mode 100644
index 0000000..853cd72
--- /dev/null
+++ b/src/app/components/manage-user/manage-user.component.html
@@ -0,0 +1,31 @@
+Manage user - {{user.name}}
+
+
+ User UID: {{user.uid}}
+
+
+
+
+
+
+
+
+
+
+
+ {{permissionToLabel[permission] ? permissionToLabel[permission] : permission}}
+
+
+ Use default
+ Yes
+ No
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/app/components/manage-user/manage-user.component.scss b/src/app/components/manage-user/manage-user.component.scss
new file mode 100644
index 0000000..167abd6
--- /dev/null
+++ b/src/app/components/manage-user/manage-user.component.scss
@@ -0,0 +1,4 @@
+.mat-radio-button {
+ margin-right: 10px;
+ margin-top: 5px;
+}
\ No newline at end of file
diff --git a/src/app/components/manage-user/manage-user.component.spec.ts b/src/app/components/manage-user/manage-user.component.spec.ts
new file mode 100644
index 0000000..f8fe3a7
--- /dev/null
+++ b/src/app/components/manage-user/manage-user.component.spec.ts
@@ -0,0 +1,25 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { ManageUserComponent } from './manage-user.component';
+
+describe('ManageUserComponent', () => {
+ let component: ManageUserComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ ManageUserComponent ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(ManageUserComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/app/components/manage-user/manage-user.component.ts b/src/app/components/manage-user/manage-user.component.ts
new file mode 100644
index 0000000..61b38f4
--- /dev/null
+++ b/src/app/components/manage-user/manage-user.component.ts
@@ -0,0 +1,69 @@
+import { Component, OnInit, Inject } from '@angular/core';
+import { PostsService } from 'app/posts.services';
+import { MAT_DIALOG_DATA } from '@angular/material/dialog';
+
+@Component({
+ selector: 'app-manage-user',
+ templateUrl: './manage-user.component.html',
+ styleUrls: ['./manage-user.component.scss']
+})
+export class ManageUserComponent implements OnInit {
+
+ user = null;
+ newPasswordInput = '';
+ available_permissions = null;
+ permissions = null;
+
+ permissionToLabel = {
+ 'filemanager': 'File manager',
+ 'settings': 'Settings access',
+ 'subscriptions': 'Subscriptions',
+ 'sharing': 'Share files',
+ 'advanced_download': 'Use advanced download mode',
+ 'downloads_manager': 'Use downloads manager'
+ }
+
+ settingNewPassword = false;
+
+ constructor(public postsService: PostsService, @Inject(MAT_DIALOG_DATA) public data: any) {
+ if (this.data) {
+ this.user = this.data.user;
+ this.available_permissions = this.postsService.available_permissions;
+ this.parsePermissions();
+ }
+ }
+
+ ngOnInit(): void {
+ }
+
+ parsePermissions() {
+ this.permissions = {};
+ for (let i = 0; i < this.available_permissions.length; i++) {
+ const permission = this.available_permissions[i];
+ if (this.user.permission_overrides.includes(permission)) {
+ if (this.user.permissions.includes(permission)) {
+ this.permissions[permission] = 'yes';
+ } else {
+ this.permissions[permission] = 'no';
+ }
+ } else {
+ this.permissions[permission] = 'default';
+ }
+ }
+ }
+
+ changeUserPermissions(change, permission) {
+ this.postsService.setUserPermission(this.user.uid, permission, change.value).subscribe(res => {
+ // console.log(res);
+ });
+ }
+
+ setNewPassword() {
+ this.settingNewPassword = true;
+ this.postsService.changeUserPassword(this.user.uid, this.newPasswordInput).subscribe(res => {
+ this.newPasswordInput = '';
+ this.settingNewPassword = false;
+ });
+ }
+
+}
diff --git a/src/app/components/modify-users/modify-users.component.html b/src/app/components/modify-users/modify-users.component.html
new file mode 100644
index 0000000..036ad2b
--- /dev/null
+++ b/src/app/components/modify-users/modify-users.component.html
@@ -0,0 +1,107 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ User name
+
+
+
+
+
+
+
+
+
+
+ {{row.name}}
+
+
+
+
+
+
+ Role
+
+
+
+
+
+ Admin
+ User
+
+
+
+
+
+ {{row.role}}
+
+
+
+
+
+
+ Actions
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/app/components/modify-users/modify-users.component.scss b/src/app/components/modify-users/modify-users.component.scss
new file mode 100644
index 0000000..558267e
--- /dev/null
+++ b/src/app/components/modify-users/modify-users.component.scss
@@ -0,0 +1,5 @@
+.edit-role {
+ position: relative;
+ top: -80px;
+ left: 35px;
+}
\ No newline at end of file
diff --git a/src/app/components/modify-users/modify-users.component.spec.ts b/src/app/components/modify-users/modify-users.component.spec.ts
new file mode 100644
index 0000000..e5e8ef8
--- /dev/null
+++ b/src/app/components/modify-users/modify-users.component.spec.ts
@@ -0,0 +1,25 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { ModifyUsersComponent } from './modify-users.component';
+
+describe('ModifyUsersComponent', () => {
+ let component: ModifyUsersComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ ModifyUsersComponent ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(ModifyUsersComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/app/components/modify-users/modify-users.component.ts b/src/app/components/modify-users/modify-users.component.ts
new file mode 100644
index 0000000..9e54fda
--- /dev/null
+++ b/src/app/components/modify-users/modify-users.component.ts
@@ -0,0 +1,219 @@
+import { Component, OnInit, Input, ViewChild, AfterViewInit } from '@angular/core';
+import { MatPaginator, PageEvent } from '@angular/material/paginator';
+import { MatSort } from '@angular/material/sort';
+import { MatTableDataSource } from '@angular/material/table';
+import { PostsService } from 'app/posts.services';
+import { MatSnackBar } from '@angular/material/snack-bar';
+import { MatDialog, MatDialogRef } from '@angular/material/dialog';
+import { AddUserDialogComponent } from 'app/dialogs/add-user-dialog/add-user-dialog.component';
+import { ManageUserComponent } from '../manage-user/manage-user.component';
+import { ManageRoleComponent } from '../manage-role/manage-role.component';
+
+@Component({
+ selector: 'app-modify-users',
+ templateUrl: './modify-users.component.html',
+ styleUrls: ['./modify-users.component.scss']
+})
+export class ModifyUsersComponent implements OnInit, AfterViewInit {
+
+ displayedColumns = ['name', 'role', 'actions'];
+ dataSource = new MatTableDataSource();
+
+ deleteDialogContentSubstring = 'Are you sure you want delete user ';
+
+ @ViewChild(MatPaginator) paginator: MatPaginator;
+ @ViewChild(MatSort) sort: MatSort;
+
+ // MatPaginator Inputs
+ length = 100;
+ @Input() pageSize = 5;
+ pageSizeOptions: number[] = [5, 10, 25, 100];
+
+ // MatPaginator Output
+ pageEvent: PageEvent;
+ users: any;
+ editObject = null;
+ constructedObject = {};
+ roles = null;
+
+
+ constructor(public postsService: PostsService, public snackBar: MatSnackBar, public dialog: MatDialog,
+ private dialogRef: MatDialogRef) { }
+
+ ngOnInit() {
+ this.getArray();
+ this.getRoles();
+ }
+
+ ngAfterViewInit() {
+ this.dataSource.paginator = this.paginator;
+ this.dataSource.sort = this.sort;
+ }
+
+ /**
+ * Set the paginator and sort after the view init since this component will
+ * be able to query its view for the initialized paginator and sort.
+ */
+ afterGetData() {
+ this.dataSource.sort = this.sort;
+ }
+
+ setPageSizeOptions(setPageSizeOptionsInput: string) {
+ this.pageSizeOptions = setPageSizeOptionsInput.split(',').map(str => +str);
+ }
+
+ applyFilter(filterValue: string) {
+ filterValue = filterValue.trim(); // Remove whitespace
+ filterValue = filterValue.toLowerCase(); // Datasource defaults to lowercase matches
+ this.dataSource.filter = filterValue;
+ }
+
+ private getArray() {
+ this.postsService.getUsers().subscribe(res => {
+ this.users = res['users'];
+ this.createAndSortData();
+ this.afterGetData();
+ });
+ }
+
+ getRoles() {
+ this.postsService.getRoles().subscribe(res => {
+ this.roles = [];
+ const roles = res['roles'];
+ const role_names = Object.keys(roles);
+ for (let i = 0; i < role_names.length; i++) {
+ const role_name = role_names[i];
+ this.roles.push({
+ name: role_name,
+ permissions: roles[role_name]['permissions']
+ });
+ }
+ });
+ }
+
+ openAddUserDialog() {
+ const dialogRef = this.dialog.open(AddUserDialogComponent);
+ dialogRef.afterClosed().subscribe(user => {
+ if (user && !user.error) {
+ this.openSnackBar('Successfully added user ' + user.name);
+ this.getArray();
+ } else if (user && user.error) {
+ this.openSnackBar('Failed to add user');
+ }
+ });
+ }
+
+ finishEditing(user_uid) {
+ let has_finished = false;
+ if (this.constructedObject && this.constructedObject['name'] && this.constructedObject['role']) {
+ if (!isEmptyOrSpaces(this.constructedObject['name']) && !isEmptyOrSpaces(this.constructedObject['role'])) {
+ has_finished = true;
+ const index_of_object = this.indexOfUser(user_uid);
+ this.users[index_of_object] = this.constructedObject;
+ this.constructedObject = {};
+ this.editObject = null;
+ this.setUser(this.users[index_of_object]);
+ this.createAndSortData();
+ }
+ }
+ }
+
+ enableEditMode(user_uid) {
+ if (this.uidInUserList(user_uid) && this.indexOfUser(user_uid) > -1) {
+ const users_index = this.indexOfUser(user_uid);
+ this.editObject = this.users[users_index];
+ this.constructedObject['name'] = this.users[users_index].name;
+ this.constructedObject['uid'] = this.users[users_index].uid;
+ this.constructedObject['role'] = this.users[users_index].role;
+ }
+ }
+
+ disableEditMode() {
+ this.editObject = null;
+ }
+
+ // checks if user is in users array by name
+ uidInUserList(user_uid) {
+ for (let i = 0; i < this.users.length; i++) {
+ if (this.users[i].uid === user_uid) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ // gets index of user in users array by name
+ indexOfUser(user_uid) {
+ for (let i = 0; i < this.users.length; i++) {
+ if (this.users[i].uid === user_uid) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ setUser(change_obj) {
+ this.postsService.changeUser(change_obj).subscribe(res => {
+ this.getArray();
+ });
+ }
+
+ manageUser(user_uid) {
+ const index_of_object = this.indexOfUser(user_uid);
+ const user_obj = this.users[index_of_object];
+ this.dialog.open(ManageUserComponent, {
+ data: {
+ user: user_obj
+ },
+ width: '65vw'
+ });
+ }
+
+ removeUser(user_uid) {
+ this.postsService.deleteUser(user_uid).subscribe(res => {
+ this.getArray();
+ }, err => {
+ this.getArray();
+ });
+ }
+
+ createAndSortData() {
+ // Sorts the data by last finished
+ this.users.sort((a, b) => b.name > a.name);
+
+ const filteredData = [];
+ for (let i = 0; i < this.users.length; i++) {
+ filteredData.push(JSON.parse(JSON.stringify(this.users[i])));
+ }
+
+ // Assign the data to the data source for the table to render
+ this.dataSource.data = filteredData;
+ }
+
+ openModifyRole(role) {
+ const dialogRef = this.dialog.open(ManageRoleComponent, {
+ data: {
+ role: role
+ }
+ });
+
+ dialogRef.afterClosed().subscribe(success => {
+ this.getRoles();
+ });
+ }
+
+ closeDialog() {
+ this.dialogRef.close();
+ }
+
+ public openSnackBar(message: string, action: string = '') {
+ this.snackBar.open(message, action, {
+ duration: 2000,
+ });
+ }
+
+}
+
+function isEmptyOrSpaces(str){
+ return str === null || str.match(/^ *$/) !== null;
+}
diff --git a/src/app/dialogs/add-user-dialog/add-user-dialog.component.html b/src/app/dialogs/add-user-dialog/add-user-dialog.component.html
new file mode 100644
index 0000000..68cb91f
--- /dev/null
+++ b/src/app/dialogs/add-user-dialog/add-user-dialog.component.html
@@ -0,0 +1,19 @@
+Register a user
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/app/dialogs/add-user-dialog/add-user-dialog.component.scss b/src/app/dialogs/add-user-dialog/add-user-dialog.component.scss
new file mode 100644
index 0000000..e69de29
diff --git a/src/app/dialogs/add-user-dialog/add-user-dialog.component.spec.ts b/src/app/dialogs/add-user-dialog/add-user-dialog.component.spec.ts
new file mode 100644
index 0000000..2eee5ca
--- /dev/null
+++ b/src/app/dialogs/add-user-dialog/add-user-dialog.component.spec.ts
@@ -0,0 +1,25 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { AddUserDialogComponent } from './add-user-dialog.component';
+
+describe('AddUserDialogComponent', () => {
+ let component: AddUserDialogComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ AddUserDialogComponent ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(AddUserDialogComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/app/dialogs/add-user-dialog/add-user-dialog.component.ts b/src/app/dialogs/add-user-dialog/add-user-dialog.component.ts
new file mode 100644
index 0000000..383103a
--- /dev/null
+++ b/src/app/dialogs/add-user-dialog/add-user-dialog.component.ts
@@ -0,0 +1,32 @@
+import { Component, OnInit } from '@angular/core';
+import { PostsService } from 'app/posts.services';
+import { MatDialogRef } from '@angular/material/dialog';
+
+@Component({
+ selector: 'app-add-user-dialog',
+ templateUrl: './add-user-dialog.component.html',
+ styleUrls: ['./add-user-dialog.component.scss']
+})
+export class AddUserDialogComponent implements OnInit {
+
+ usernameInput = '';
+ passwordInput = '';
+
+ constructor(private postsService: PostsService, public dialogRef: MatDialogRef) { }
+
+ ngOnInit(): void {
+ }
+
+ createUser() {
+ this.postsService.register(this.usernameInput, this.passwordInput).subscribe(res => {
+ if (res['user']) {
+ this.dialogRef.close(res['user']);
+ } else {
+ this.dialogRef.close({error: 'Unknown error'});
+ }
+ }, err => {
+ this.dialogRef.close({error: err});
+ });
+ }
+
+}
diff --git a/src/app/dialogs/set-default-admin-dialog/set-default-admin-dialog.component.html b/src/app/dialogs/set-default-admin-dialog/set-default-admin-dialog.component.html
index 1d800b9..4cfbda1 100644
--- a/src/app/dialogs/set-default-admin-dialog/set-default-admin-dialog.component.html
+++ b/src/app/dialogs/set-default-admin-dialog/set-default-admin-dialog.component.html
@@ -7,7 +7,7 @@
diff --git a/src/app/main/main.component.html b/src/app/main/main.component.html
index 46079fa..3d41d80 100644
--- a/src/app/main/main.component.html
+++ b/src/app/main/main.component.html
@@ -186,7 +186,7 @@
-
+
diff --git a/src/app/main/main.component.ts b/src/app/main/main.component.ts
index 36bd9f2..aef078f 100644
--- a/src/app/main/main.component.ts
+++ b/src/app/main/main.component.ts
@@ -3,7 +3,6 @@ import {PostsService} from '../posts.services';
import {FileCardComponent} from '../file-card/file-card.component';
import { Observable } from 'rxjs/Observable';
import {FormControl, Validators} from '@angular/forms';
-import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
import { MatDialog } from '@angular/material/dialog';
import { MatSnackBar } from '@angular/material/snack-bar';
import { saveAs } from 'file-saver';
@@ -215,7 +214,7 @@ export class MainComponent implements OnInit {
simulatedOutput = '';
- constructor(private postsService: PostsService, private youtubeSearch: YoutubeSearchService, public snackBar: MatSnackBar,
+ constructor(public postsService: PostsService, private youtubeSearch: YoutubeSearchService, public snackBar: MatSnackBar,
private router: Router, public dialog: MatDialog, private platform: Platform, private route: ActivatedRoute) {
this.audioOnly = false;
}
@@ -242,7 +241,8 @@ export class MainComponent implements OnInit {
this.postsService.config['API']['youtube_API_key'];
this.youtubeAPIKey = this.youtubeSearchEnabled ? this.postsService.config['API']['youtube_API_key'] : null;
this.allowQualitySelect = this.postsService.config['Extra']['allow_quality_select'];
- this.allowAdvancedDownload = this.postsService.config['Advanced']['allow_advanced_download'];
+ this.allowAdvancedDownload = this.postsService.config['Advanced']['allow_advanced_download']
+ && (!this.postsService.isLoggedIn || this.postsService.permissions.includes('advanced_download'));
this.useDefaultDownloadingAgent = this.postsService.config['Advanced']['use_default_downloading_agent'];
this.customDownloadingAgent = this.postsService.config['Advanced']['custom_downloading_agent'];
diff --git a/src/app/player/player.component.html b/src/app/player/player.component.html
index 6c03c3e..fce9125 100644
--- a/src/app/player/player.component.html
+++ b/src/app/player/player.component.html
@@ -26,10 +26,10 @@
1">
-
+
-
+
\ No newline at end of file
diff --git a/src/app/player/player.component.ts b/src/app/player/player.component.ts
index 84bba1c..2cad9c6 100644
--- a/src/app/player/player.component.ts
+++ b/src/app/player/player.component.ts
@@ -90,7 +90,7 @@ export class PlayerComponent implements OnInit {
}
}
- constructor(private postsService: PostsService, private route: ActivatedRoute, private dialog: MatDialog, private router: Router,
+ constructor(public postsService: PostsService, private route: ActivatedRoute, private dialog: MatDialog, private router: Router,
public snackBar: MatSnackBar) {
}
diff --git a/src/app/posts.services.ts b/src/app/posts.services.ts
index 42c6168..a4bb0dc 100644
--- a/src/app/posts.services.ts
+++ b/src/app/posts.services.ts
@@ -10,6 +10,7 @@ import { DOCUMENT } from '@angular/common';
import { BehaviorSubject } from 'rxjs';
import { v4 as uuid } from 'uuid';
import { MatSnackBar } from '@angular/material/snack-bar';
+import * as Fingerprint2 from 'fingerprintjs2';
@Injectable()
export class PostsService implements CanActivate {
@@ -30,9 +31,13 @@ export class PostsService implements CanActivate {
debugMode = false;
+ // must be reset after logout
isLoggedIn = false;
token = null;
user = null;
+ permissions = null;
+
+ available_permissions = null;
reload_config = new BehaviorSubject
(false);
config_reloaded = new BehaviorSubject(false);
@@ -48,13 +53,13 @@ export class PostsService implements CanActivate {
// this.startPath = window.location.href + '/api/';
// this.startPathSSL = window.location.href + '/api/';
this.path = this.document.location.origin + '/api/';
- this.session_id = uuid();
+
if (isDevMode()) {
this.debugMode = true;
this.path = 'http://localhost:17442/api/';
}
- this.http_params = `apiKey=${this.auth_token}&sessionID=${this.session_id}`
+ this.http_params = `apiKey=${this.auth_token}`
this.httpOptions = {
params: new HttpParams({
@@ -62,6 +67,12 @@ export class PostsService implements CanActivate {
}),
};
+ Fingerprint2.get(components => {
+ // set identity as user id doesn't necessarily exist
+ this.session_id = Fingerprint2.x64hash128(components.map(function (pair) { return pair.value; }).join(), 31);
+ this.httpOptions.params = this.httpOptions.params.set('sessionID', this.session_id);
+ });
+
// get config
this.loadNavItems().subscribe(res => {
const result = !this.debugMode ? res['config_file'] : res;
@@ -71,11 +82,8 @@ export class PostsService implements CanActivate {
// login stuff
if (localStorage.getItem('jwt_token')) {
this.token = localStorage.getItem('jwt_token');
- this.httpOptions = {
- params: new HttpParams({
- fromString: `apiKey=${this.auth_token}&sessionID=${this.session_id}&jwt=${this.token}`
- }),
- };
+ this.httpOptions.params = this.httpOptions.params.set('jwt', this.token);
+
this.jwtAuth();
} else {
this.sendToLogin();
@@ -321,18 +329,16 @@ export class PostsService implements CanActivate {
return this.http.get('https://api.github.com/repos/tzahi12345/youtubedl-material/releases');
}
- afterLogin(user, token) {
+ afterLogin(user, token, permissions, available_permissions) {
this.isLoggedIn = true;
this.user = user;
+ this.permissions = permissions;
+ this.available_permissions = available_permissions;
this.token = token;
localStorage.setItem('jwt_token', this.token);
- this.httpOptions = {
- params: new HttpParams({
- fromString: `apiKey=${this.auth_token}&sessionID=${this.session_id}&jwt=${this.token}`
- }),
- };
+ this.httpOptions.params = this.httpOptions.params.set('jwt', this.token);
// needed to re-initialize parts of app after login
this.config_reloaded.next(true);
@@ -347,7 +353,7 @@ export class PostsService implements CanActivate {
const call = this.http.post(this.path + 'auth/login', {userid: username, password: password}, this.httpOptions);
call.subscribe(res => {
if (res['token']) {
- this.afterLogin(res['user'], res['token']);
+ this.afterLogin(res['user'], res['token'], res['permissions'], res['available_permissions']);
}
});
return call;
@@ -358,7 +364,7 @@ export class PostsService implements CanActivate {
const call = this.http.post(this.path + 'auth/jwtAuth', {}, this.httpOptions);
call.subscribe(res => {
if (res['token']) {
- this.afterLogin(res['user'], res['token']);
+ this.afterLogin(res['user'], res['token'], res['permissions'], res['available_permissions']);
this.setInitialized();
}
}, err => {
@@ -371,6 +377,7 @@ export class PostsService implements CanActivate {
logout() {
this.user = null;
+ this.permissions = null;
this.isLoggedIn = false;
localStorage.setItem('jwt_token', null);
if (this.router.url !== '/login') {
@@ -430,7 +437,9 @@ export class PostsService implements CanActivate {
}
checkAdminCreationStatus() {
- console.log('checking c stat');
+ if (!this.config['Advanced']['multi_user_mode']) {
+ return;
+ }
this.adminExists().subscribe(res => {
if (!res['exists']) {
// must create admin account
@@ -439,6 +448,36 @@ export class PostsService implements CanActivate {
});
}
+ changeUser(change_obj) {
+ return this.http.post(this.path + 'changeUser', {change_object: change_obj}, this.httpOptions);
+ }
+
+ deleteUser(uid) {
+ return this.http.post(this.path + 'deleteUser', {uid: uid}, this.httpOptions);
+ }
+
+ changeUserPassword(user_uid, new_password) {
+ return this.http.post(this.path + 'auth/changePassword', {user_uid: user_uid, new_password: new_password}, this.httpOptions);
+ }
+
+ getUsers() {
+ return this.http.post(this.path + 'getUsers', {}, this.httpOptions);
+ }
+
+ getRoles() {
+ return this.http.post(this.path + 'getRoles', {}, this.httpOptions);
+ }
+
+ setUserPermission(user_uid, permission, new_value) {
+ return this.http.post(this.path + 'changeUserPermissions', {user_uid: user_uid, permission: permission, new_value: new_value},
+ this.httpOptions);
+ }
+
+ setRolePermission(role_name, permission, new_value) {
+ return this.http.post(this.path + 'changeRolePermissions', {role: role_name, permission: permission, new_value: new_value},
+ this.httpOptions);
+ }
+
public openSnackBar(message: string, action: string = '') {
this.snackBar.open(message, action, {
duration: 2000,
diff --git a/src/app/settings/settings.component.html b/src/app/settings/settings.component.html
index e2e9102..b2696d5 100644
--- a/src/app/settings/settings.component.html
+++ b/src/app/settings/settings.component.html
@@ -266,6 +266,9 @@
+
+
+
diff --git a/src/app/settings/settings.component.ts b/src/app/settings/settings.component.ts
index c3021a3..c31c28a 100644
--- a/src/app/settings/settings.component.ts
+++ b/src/app/settings/settings.component.ts
@@ -39,7 +39,7 @@ export class SettingsComponent implements OnInit {
this._settingsSame = val;
}
- constructor(private postsService: PostsService, private snackBar: MatSnackBar, private sanitizer: DomSanitizer,
+ constructor(public postsService: PostsService, private snackBar: MatSnackBar, private sanitizer: DomSanitizer,
private dialog: MatDialog) { }
ngOnInit() {