mirror of
https://github.com/Tzahi12345/YoutubeDL-Material.git
synced 2026-03-17 18:20:56 +03:00
jwt auth scaffolding
logging in now works UI login component created
This commit is contained in:
@@ -1629,9 +1629,14 @@ app.post('/api/fileStatusMp4', function(req, res) {
|
||||
|
||||
// gets all download mp3s
|
||||
app.get('/api/getMp3s', function(req, res) {
|
||||
const multiUserMode = config_api.getConfigItem('ytdl_multi_user_mode');
|
||||
var mp3s = db.get('files.audio').value(); // getMp3s();
|
||||
var playlists = db.get('playlists.audio').value();
|
||||
|
||||
if (req.query.jwt && multiUserMode) {
|
||||
// mp3s = db.get
|
||||
}
|
||||
|
||||
res.send({
|
||||
mp3s: mp3s,
|
||||
playlists: playlists
|
||||
@@ -2313,8 +2318,7 @@ app.get('/api/audio/:id', function(req , res){
|
||||
app.post('/api/auth/register'
|
||||
, auth.registerUser);
|
||||
app.post('/api/auth/login'
|
||||
// , auth.passport.authenticate('basic',{session:false}) // causes challenge pop-up on 401
|
||||
, auth.authenticateViaPassport
|
||||
, auth.passport.authenticate('local', {})
|
||||
, auth.generateJWT
|
||||
, auth.returnAuthResponse
|
||||
);
|
||||
|
||||
@@ -8,6 +8,15 @@ db.defaults(
|
||||
}
|
||||
).write();
|
||||
|
||||
var LocalStrategy = require('passport-local').Strategy;
|
||||
var JwtStrategy = require('passport-jwt').Strategy,
|
||||
ExtractJwt = require('passport-jwt').ExtractJwt;
|
||||
var opts = {}
|
||||
opts.jwtFromRequest = ExtractJwt.fromUrlQueryParameter('jwt');
|
||||
opts.secretOrKey = 'secret';
|
||||
opts.issuer = 'example.com';
|
||||
opts.audience = 'example.com';
|
||||
|
||||
/*************************
|
||||
* Authentication module
|
||||
************************/
|
||||
@@ -23,11 +32,18 @@ const SERVER_SECRET = uuid();
|
||||
exports.passport = require('passport');
|
||||
var BasicStrategy = require('passport-http').BasicStrategy;
|
||||
|
||||
exports.passport.serializeUser(function(user, done) {
|
||||
done(null, user);
|
||||
});
|
||||
|
||||
exports.passport.deserializeUser(function(user, done) {
|
||||
done(null, user);
|
||||
});
|
||||
|
||||
/***************************************
|
||||
* Register user with hashed password
|
||||
**************************************/
|
||||
exports.registerUser = function(req, res) {
|
||||
console.log('got here');
|
||||
var userid = req.body.userid;
|
||||
var username = req.body.username;
|
||||
var plaintextPassword = req.body.password;
|
||||
@@ -76,10 +92,31 @@ exports.registerUser = function(req, res) {
|
||||
* This checks that the credentials are valid.
|
||||
* If so, passes the user info to the next middleware.
|
||||
************************************************/
|
||||
exports.passport.use(new BasicStrategy(
|
||||
exports.passport.use(new JwtStrategy(opts, function(jwt_payload, done) {
|
||||
const user = db.get('users').find({uid: jwt_payload.sub}).value();
|
||||
if (user) {
|
||||
return done(null, user);
|
||||
} else {
|
||||
return done(null, false);
|
||||
// or you could create a new account
|
||||
}
|
||||
}));
|
||||
|
||||
exports.passport.use(new LocalStrategy({
|
||||
usernameField: 'userid',
|
||||
passwordField: 'password'},
|
||||
function(username, password, done) {
|
||||
const user = db.get('users').find({name: username}).value();
|
||||
if (!user) { return done(null, false); }
|
||||
if (user) {
|
||||
return done(null, bcrypt.compareSync(password, user.passhash) ? user : false);
|
||||
}
|
||||
}
|
||||
));
|
||||
|
||||
/*passport.use(new BasicStrategy(
|
||||
function(userid, plainTextPassword, done) {
|
||||
// console.log('BasicStrategy: verifying credentials');
|
||||
const user = db.get('users').find({uid: userid}).value();
|
||||
const user = db.get('users').find({name: userid}).value();
|
||||
if (user) {
|
||||
var hashedPwd = user.passhash;
|
||||
return bcrypt.compare(plainTextPassword, hashedPwd);
|
||||
@@ -88,6 +125,7 @@ exports.passport.use(new BasicStrategy(
|
||||
}
|
||||
}
|
||||
));
|
||||
*/
|
||||
|
||||
/*************************************************************
|
||||
* This is a wrapper for auth.passport.authenticate().
|
||||
@@ -96,6 +134,7 @@ exports.passport.use(new BasicStrategy(
|
||||
* Browser's will pop-up up dialog when status is 401 and
|
||||
* "WWW-Authenticate:Basic..."
|
||||
*************************************************************/
|
||||
/*
|
||||
exports.authenticateViaPassport = function(req, res, next) {
|
||||
exports.passport.authenticate('basic',{session:false},
|
||||
function(err, user, info) {
|
||||
@@ -109,6 +148,7 @@ exports.authenticateViaPassport = function(req, res, next) {
|
||||
}
|
||||
)(req, res, next);
|
||||
};
|
||||
*/
|
||||
|
||||
/**********************************
|
||||
* Generating/Signing a JWT token
|
||||
@@ -158,6 +198,12 @@ exports.ensureAuthenticatedElseError = function(req, res, next) {
|
||||
}
|
||||
}
|
||||
|
||||
// video stuff
|
||||
|
||||
exports.getUserVideos(type) {
|
||||
|
||||
}
|
||||
|
||||
function getToken(queryParams) {
|
||||
if (queryParams && queryParams.jwt) {
|
||||
var parted = queryParams.jwt.split(' ');
|
||||
|
||||
@@ -4,11 +4,15 @@ import { MainComponent } from './main/main.component';
|
||||
import { PlayerComponent } from './player/player.component';
|
||||
import { SubscriptionsComponent } from './subscriptions/subscriptions.component';
|
||||
import { SubscriptionComponent } from './subscription/subscription/subscription.component';
|
||||
import { PostsService } from './posts.services';
|
||||
import { LoginComponent } from './components/login/login.component';
|
||||
|
||||
const routes: Routes = [
|
||||
{ path: 'home', component: MainComponent },
|
||||
{ path: 'player', component: PlayerComponent},
|
||||
{ path: 'subscriptions', component: SubscriptionsComponent },
|
||||
{ path: 'subscription', component: SubscriptionComponent },
|
||||
{ path: 'home', component: MainComponent, canActivate: [PostsService] },
|
||||
{ path: 'player', component: PlayerComponent, canActivate: [PostsService]},
|
||||
{ path: 'subscriptions', component: SubscriptionsComponent, canActivate: [PostsService] },
|
||||
{ path: 'subscription', component: SubscriptionComponent, canActivate: [PostsService] },
|
||||
{ path: 'login', component: LoginComponent },
|
||||
{ path: '', redirectTo: '/home', pathMatch: 'full' },
|
||||
];
|
||||
|
||||
|
||||
@@ -57,6 +57,7 @@ import { ArgModifierDialogComponent, HighlightPipe } from './dialogs/arg-modifie
|
||||
import { UpdaterComponent } from './updater/updater.component';
|
||||
import { UpdateProgressDialogComponent } from './dialogs/update-progress-dialog/update-progress-dialog.component';
|
||||
import { ShareMediaDialogComponent } from './dialogs/share-media-dialog/share-media-dialog.component';
|
||||
import { LoginComponent } from './components/login/login.component';
|
||||
registerLocaleData(es, 'es');
|
||||
|
||||
export function isVisible({ event, element, scrollContainer, offset }: IsVisibleProps<any>) {
|
||||
@@ -85,7 +86,8 @@ export function isVisible({ event, element, scrollContainer, offset }: IsVisible
|
||||
HighlightPipe,
|
||||
UpdaterComponent,
|
||||
UpdateProgressDialogComponent,
|
||||
ShareMediaDialogComponent
|
||||
ShareMediaDialogComponent,
|
||||
LoginComponent
|
||||
],
|
||||
imports: [
|
||||
CommonModule,
|
||||
|
||||
22
src/app/components/login/login.component.html
Normal file
22
src/app/components/login/login.component.html
Normal file
@@ -0,0 +1,22 @@
|
||||
<mat-card class="login-card">
|
||||
<mat-tab-group>
|
||||
<mat-tab label="Login">
|
||||
<div style="margin-top: 10px;">
|
||||
<mat-form-field>
|
||||
<input [(ngModel)]="usernameInput" matInput placeholder="User name">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div>
|
||||
<mat-form-field>
|
||||
<input [(ngModel)]="passwordInput" type="password" matInput placeholder="Password">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div style="margin-bottom: 10px; margin-top: 10px;">
|
||||
<button [disabled]="loggingIn" color="primary" (click)="login()" mat-raised-button>Login</button>
|
||||
</div>
|
||||
</mat-tab>
|
||||
<mat-tab *ngIf="registrationEnabled" label="Register">
|
||||
|
||||
</mat-tab>
|
||||
</mat-tab-group>
|
||||
</mat-card>
|
||||
6
src/app/components/login/login.component.scss
Normal file
6
src/app/components/login/login.component.scss
Normal file
@@ -0,0 +1,6 @@
|
||||
.login-card {
|
||||
max-width: 600px;
|
||||
width: 80%;
|
||||
margin: 0 auto;
|
||||
margin-top: 20px;
|
||||
}
|
||||
25
src/app/components/login/login.component.spec.ts
Normal file
25
src/app/components/login/login.component.spec.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { LoginComponent } from './login.component';
|
||||
|
||||
describe('LoginComponent', () => {
|
||||
let component: LoginComponent;
|
||||
let fixture: ComponentFixture<LoginComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ LoginComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(LoginComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
31
src/app/components/login/login.component.ts
Normal file
31
src/app/components/login/login.component.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { PostsService } from 'app/posts.services';
|
||||
|
||||
@Component({
|
||||
selector: 'app-login',
|
||||
templateUrl: './login.component.html',
|
||||
styleUrls: ['./login.component.scss']
|
||||
})
|
||||
export class LoginComponent implements OnInit {
|
||||
|
||||
usernameInput = '';
|
||||
passwordInput = '';
|
||||
registrationEnabled = true;
|
||||
loggingIn = false;
|
||||
|
||||
constructor(private postsService: PostsService) { }
|
||||
|
||||
ngOnInit(): void {
|
||||
}
|
||||
|
||||
login() {
|
||||
this.loggingIn = true;
|
||||
this.postsService.login(this.usernameInput, this.passwordInput).subscribe(res => {
|
||||
this.loggingIn = false;
|
||||
console.log(res);
|
||||
}, err => {
|
||||
this.loggingIn = false;
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -5,12 +5,12 @@ import 'rxjs/add/operator/map';
|
||||
import 'rxjs/add/operator/catch';
|
||||
import 'rxjs/add/observable/throw';
|
||||
import { THEMES_CONFIG } from '../themes';
|
||||
import { Router } from '@angular/router';
|
||||
import { Router, CanActivate } from '@angular/router';
|
||||
import { DOCUMENT } from '@angular/common';
|
||||
import { BehaviorSubject } from 'rxjs';
|
||||
|
||||
@Injectable()
|
||||
export class PostsService {
|
||||
export class PostsService implements CanActivate {
|
||||
path = '';
|
||||
audioFolder = '';
|
||||
videoFolder = '';
|
||||
@@ -24,6 +24,10 @@ export class PostsService {
|
||||
httpOptions = null;
|
||||
|
||||
debugMode = false;
|
||||
|
||||
isLoggedIn = false;
|
||||
token = null;
|
||||
user = null;
|
||||
constructor(private http: HttpClient, private router: Router, @Inject(DOCUMENT) private document: Document) {
|
||||
console.log('PostsService Initialized...');
|
||||
// this.startPath = window.location.href + '/api/';
|
||||
@@ -41,6 +45,11 @@ export class PostsService {
|
||||
}),
|
||||
};
|
||||
}
|
||||
canActivate(route, state): boolean {
|
||||
console.log(route);
|
||||
return true;
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
|
||||
setTheme(theme) {
|
||||
this.theme = this.THEMES_CONFIG[theme];
|
||||
@@ -233,4 +242,27 @@ export class PostsService {
|
||||
return this.http.get('https://api.github.com/repos/tzahi12345/youtubedl-material/releases');
|
||||
}
|
||||
|
||||
afterLogin(user, token) {
|
||||
this.isLoggedIn = true;
|
||||
this.user = user;
|
||||
this.token = token;
|
||||
|
||||
this.httpOptions = {
|
||||
params: new HttpParams({
|
||||
fromString: `apiKey=${this.auth_token}&jwt=${this.token}`
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
||||
// user methods
|
||||
login(username, password) {
|
||||
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']);
|
||||
}
|
||||
});
|
||||
return call;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user