mirror of
https://github.com/Tzahi12345/YoutubeDL-Material.git
synced 2026-03-20 11:41:00 +03:00
Added UI flow for creating default admin account. Dialog will show up after enabling or in the login menu if the admin account isn't present
This commit is contained in:
@@ -2735,6 +2735,16 @@ app.post('/api/auth/jwtAuth'
|
||||
, auth_api.generateJWT
|
||||
, auth_api.returnAuthResponse
|
||||
);
|
||||
app.post('/api/auth/changePassword', optionalJwt, async (req, res) => {
|
||||
let user_uid = req.user.uid;
|
||||
let password = req.body.password;
|
||||
let success = await auth_api.changeUserPassword(user_uid, password);
|
||||
res.send({success: success});
|
||||
});
|
||||
app.post('/api/auth/adminExists', async (req, res) => {
|
||||
let exists = auth_api.adminExists();
|
||||
res.send({exists: exists});
|
||||
});
|
||||
|
||||
app.use(function(req, res, next) {
|
||||
//if the request is not html then move along
|
||||
|
||||
@@ -96,7 +96,8 @@ exports.registerUser = function(req, res) {
|
||||
video: []
|
||||
},
|
||||
subscriptions: [],
|
||||
created: Date.now()
|
||||
created: Date.now(),
|
||||
role: userid === 'admin' ? 'admin' : 'user'
|
||||
};
|
||||
// check if user exists
|
||||
if (users_db.get('users').find({uid: userid}).value()) {
|
||||
@@ -238,6 +239,23 @@ exports.ensureAuthenticatedElseError = function(req, res, next) {
|
||||
}
|
||||
}
|
||||
|
||||
// change password
|
||||
exports.changeUserPassword = async function(user_uid, new_pass) {
|
||||
return new Promise(resolve => {
|
||||
bcrypt.hash(new_pass, saltRounds)
|
||||
.then(function(hash) {
|
||||
users_db.get('users').find({uid: user_uid}).assign({passhash: hash}).write();
|
||||
resolve(true);
|
||||
}).catch(err => {
|
||||
resolve(false);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
exports.adminExists = function() {
|
||||
return !!users_db.get('users').find({uid: 'admin'}).value();
|
||||
}
|
||||
|
||||
// video stuff
|
||||
|
||||
exports.getUserVideos = function(user_uid, type) {
|
||||
|
||||
@@ -24,6 +24,7 @@ import { SettingsComponent } from './settings/settings.component';
|
||||
import { CheckOrSetPinDialogComponent } from './dialogs/check-or-set-pin-dialog/check-or-set-pin-dialog.component';
|
||||
import { AboutDialogComponent } from './dialogs/about-dialog/about-dialog.component';
|
||||
import { UserProfileDialogComponent } from './dialogs/user-profile-dialog/user-profile-dialog.component';
|
||||
import { SetDefaultAdminDialogComponent } from './dialogs/set-default-admin-dialog/set-default-admin-dialog.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
@@ -148,6 +149,18 @@ onSetTheme(theme, old_theme) {
|
||||
} else {
|
||||
//
|
||||
}
|
||||
this.postsService.open_create_default_admin_dialog.subscribe(open => {
|
||||
if (open) {
|
||||
const dialogRef = this.dialog.open(SetDefaultAdminDialogComponent);
|
||||
dialogRef.afterClosed().subscribe(success => {
|
||||
if (success) {
|
||||
if (this.router.url !== '/login') { this.router.navigate(['/login']); }
|
||||
} else {
|
||||
console.error('Failed to create default admin account. See logs for details.');
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -60,6 +60,7 @@ import { ShareMediaDialogComponent } from './dialogs/share-media-dialog/share-me
|
||||
import { LoginComponent } from './components/login/login.component';
|
||||
import { DownloadsComponent } from './components/downloads/downloads.component';
|
||||
import { UserProfileDialogComponent } from './dialogs/user-profile-dialog/user-profile-dialog.component';
|
||||
import { SetDefaultAdminDialogComponent } from './dialogs/set-default-admin-dialog/set-default-admin-dialog.component';
|
||||
registerLocaleData(es, 'es');
|
||||
|
||||
export function isVisible({ event, element, scrollContainer, offset }: IsVisibleProps<any>) {
|
||||
@@ -91,7 +92,8 @@ export function isVisible({ event, element, scrollContainer, offset }: IsVisible
|
||||
ShareMediaDialogComponent,
|
||||
LoginComponent,
|
||||
DownloadsComponent,
|
||||
UserProfileDialogComponent
|
||||
UserProfileDialogComponent,
|
||||
SetDefaultAdminDialogComponent
|
||||
],
|
||||
imports: [
|
||||
CommonModule,
|
||||
|
||||
@@ -30,6 +30,13 @@ export class LoginComponent implements OnInit {
|
||||
if (this.postsService.isLoggedIn) {
|
||||
this.router.navigate(['/home']);
|
||||
}
|
||||
this.postsService.service_initialized.subscribe(init => {
|
||||
if (init) {
|
||||
if (!this.postsService.config['Advanced']['multi_user_mode']) {
|
||||
this.router.navigate(['/home']);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
login() {
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
<h4 mat-dialog-title><ng-container i18n="Create admin account dialog title">Create admin account</ng-container></h4>
|
||||
|
||||
<mat-dialog-content>
|
||||
<div>
|
||||
<p i18n="No default admin detected explanation">No default admin account detected. This will create and set the password for an admin account with the user name as 'admin'.</p>
|
||||
</div>
|
||||
<div style="position: relative">
|
||||
<div>
|
||||
<mat-form-field color="accent">
|
||||
<input type="password" (keyup.enter)="create()" matInput [(ngModel)]="input" placeholder="Password" placeholder-i18n="Password">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</div>
|
||||
</mat-dialog-content>
|
||||
|
||||
<mat-dialog-actions>
|
||||
<button [disabled]="input.length === 0" color="accent" style="margin-bottom: 12px;" (click)="create()" mat-raised-button><ng-container i18n="Create">Create</ng-container></button>
|
||||
<div class="spinner-div"><mat-spinner [diameter]="25" *ngIf="creating"></mat-spinner></div>
|
||||
</mat-dialog-actions>
|
||||
@@ -0,0 +1,5 @@
|
||||
.spinner-div {
|
||||
position: relative;
|
||||
left: 10px;
|
||||
bottom: 5px;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { SetDefaultAdminDialogComponent } from './set-default-admin-dialog.component';
|
||||
|
||||
describe('SetDefaultAdminDialogComponent', () => {
|
||||
let component: SetDefaultAdminDialogComponent;
|
||||
let fixture: ComponentFixture<SetDefaultAdminDialogComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ SetDefaultAdminDialogComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(SetDefaultAdminDialogComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,33 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { PostsService } from 'app/posts.services';
|
||||
import { MatDialogRef } from '@angular/material/dialog';
|
||||
|
||||
@Component({
|
||||
selector: 'app-set-default-admin-dialog',
|
||||
templateUrl: './set-default-admin-dialog.component.html',
|
||||
styleUrls: ['./set-default-admin-dialog.component.scss']
|
||||
})
|
||||
export class SetDefaultAdminDialogComponent implements OnInit {
|
||||
creating = false;
|
||||
input = '';
|
||||
constructor(private postsService: PostsService, public dialogRef: MatDialogRef<SetDefaultAdminDialogComponent>) { }
|
||||
|
||||
ngOnInit(): void {
|
||||
}
|
||||
|
||||
create() {
|
||||
this.creating = true;
|
||||
this.postsService.createAdminAccount(this.input).subscribe(res => {
|
||||
this.creating = false;
|
||||
if (res['success']) {
|
||||
this.dialogRef.close(true);
|
||||
} else {
|
||||
this.dialogRef.close(false);
|
||||
}
|
||||
}, err => {
|
||||
console.log(err);
|
||||
this.dialogRef.close(false);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -39,6 +39,8 @@ export class PostsService implements CanActivate {
|
||||
service_initialized = new BehaviorSubject<boolean>(false);
|
||||
initialized = false;
|
||||
|
||||
open_create_default_admin_dialog = new BehaviorSubject<boolean>(false);
|
||||
|
||||
config = null;
|
||||
constructor(private http: HttpClient, private router: Router, @Inject(DOCUMENT) private document: Document,
|
||||
public snackBar: MatSnackBar) {
|
||||
@@ -75,6 +77,8 @@ export class PostsService implements CanActivate {
|
||||
}),
|
||||
};
|
||||
this.jwtAuth();
|
||||
} else {
|
||||
this.sendToLogin();
|
||||
}
|
||||
} else {
|
||||
this.setInitialized();
|
||||
@@ -398,6 +402,7 @@ export class PostsService implements CanActivate {
|
||||
}
|
||||
|
||||
sendToLogin() {
|
||||
this.checkAdminCreationStatus();
|
||||
if (this.router.url === '/login') {
|
||||
return;
|
||||
}
|
||||
@@ -414,6 +419,26 @@ export class PostsService implements CanActivate {
|
||||
this.config_reloaded.next(true);
|
||||
}
|
||||
|
||||
adminExists() {
|
||||
return this.http.post(this.path + 'auth/adminExists', {}, this.httpOptions);
|
||||
}
|
||||
|
||||
createAdminAccount(password) {
|
||||
return this.http.post(this.path + 'auth/register', {userid: 'admin',
|
||||
username: 'admin',
|
||||
password: password}, this.httpOptions);
|
||||
}
|
||||
|
||||
checkAdminCreationStatus() {
|
||||
console.log('checking c stat');
|
||||
this.adminExists().subscribe(res => {
|
||||
if (!res['exists']) {
|
||||
// must create admin account
|
||||
this.open_create_default_admin_dialog.next(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public openSnackBar(message: string, action: string = '') {
|
||||
this.snackBar.open(message, action, {
|
||||
duration: 2000,
|
||||
|
||||
@@ -63,6 +63,10 @@ export class SettingsComponent implements OnInit {
|
||||
const settingsToSave = {'YoutubeDLMaterial': this.new_config};
|
||||
this.postsService.setConfig(settingsToSave).subscribe(res => {
|
||||
if (res['success']) {
|
||||
if (!this.initial_config['Advanced']['multi_user_mode'] && this.new_config['Advanced']['multi_user_mode']) {
|
||||
// multi user mode was enabled, let's check if default admin account exists
|
||||
this.postsService.checkAdminCreationStatus();
|
||||
}
|
||||
// sets new config as old config
|
||||
this.initial_config = JSON.parse(JSON.stringify(this.new_config));
|
||||
this.postsService.reload_config.next(true);
|
||||
|
||||
Reference in New Issue
Block a user