upgrade to newest backend
This commit is contained in:
parent
e6742f1cc5
commit
72178dd7c4
@ -4,7 +4,7 @@ import {Routes, RouterModule} from '@angular/router';
|
|||||||
import {AuthGuard, AuthUpdateGuard, AuthenticatedGuard, AnonymousGuard} from './auth/auth.guard';
|
import {AuthGuard, AuthUpdateGuard, AuthenticatedGuard, AnonymousGuard} from './auth/auth.guard';
|
||||||
import {ImprintComponent, PrivacyPolicyComponent, TermsOfServiceComponent} from './pages/general/general.component';
|
import {ImprintComponent, PrivacyPolicyComponent, TermsOfServiceComponent} from './pages/general/general.component';
|
||||||
import {FormLoginComponent} from './pages/form-login/form-login.component';
|
import {FormLoginComponent} from './pages/form-login/form-login.component';
|
||||||
import {FormLoginTotpComponent} from './pages/form-login-totp/form-login-totp.component';
|
import {FormLogin2FAComponent} from './pages/form-login-2fa/form-login-2fa.component';
|
||||||
import {PasswordComponent} from './pages/password/password.component';
|
import {PasswordComponent} from './pages/password/password.component';
|
||||||
import {PasswordResetComponent} from './pages/password-reset/password-reset.component';
|
import {PasswordResetComponent} from './pages/password-reset/password-reset.component';
|
||||||
import {AccountComponent} from './pages/account/account.component';
|
import {AccountComponent} from './pages/account/account.component';
|
||||||
@ -30,9 +30,9 @@ const routes: Routes = [
|
|||||||
{path: 'privacy-policy', component: PrivacyPolicyComponent, canActivate: [AuthUpdateGuard]},
|
{path: 'privacy-policy', component: PrivacyPolicyComponent, canActivate: [AuthUpdateGuard]},
|
||||||
{path: 'terms-of-service', component: TermsOfServiceComponent, canActivate: [AuthUpdateGuard]},
|
{path: 'terms-of-service', component: TermsOfServiceComponent, canActivate: [AuthUpdateGuard]},
|
||||||
{path: 'login', component: FormLoginComponent, canActivate: [AnonymousGuard]},
|
{path: 'login', component: FormLoginComponent, canActivate: [AnonymousGuard]},
|
||||||
{path: 'login/totp', component: FormLoginTotpComponent, canActivate: [AnonymousGuard]},
|
{path: 'login/2fa', component: FormLogin2FAComponent, canActivate: [AnonymousGuard]},
|
||||||
{path: 'service-login', component: FormLoginComponent, canActivate: [AnonymousGuard]},
|
{path: 'service-login', component: FormLoginComponent, canActivate: [AnonymousGuard]},
|
||||||
{path: 'service-login/totp', component: FormLoginTotpComponent, canActivate: [AnonymousGuard]},
|
{path: 'service-login/2fa', component: FormLogin2FAComponent, canActivate: [AnonymousGuard]},
|
||||||
{path: 'password', component: PasswordComponent, canActivate: [AnonymousGuard]},
|
{path: 'password', component: PasswordComponent, canActivate: [AnonymousGuard]},
|
||||||
{path: 'password-reset', component: PasswordResetComponent, canActivate: [AnonymousGuard]},
|
{path: 'password-reset', component: PasswordResetComponent, canActivate: [AnonymousGuard]},
|
||||||
{path: 'services', component: ServicesComponent, canActivate: [AuthenticatedGuard]},
|
{path: 'services', component: ServicesComponent, canActivate: [AuthenticatedGuard]},
|
||||||
|
@ -18,9 +18,8 @@ import {AccountComponent} from './pages/account/account.component';
|
|||||||
import {ServicesComponent} from './pages/services/services.component';
|
import {ServicesComponent} from './pages/services/services.component';
|
||||||
import {AppComponent} from './app.component';
|
import {AppComponent} from './app.component';
|
||||||
import {LoginComponent} from './pages/login/login.component';
|
import {LoginComponent} from './pages/login/login.component';
|
||||||
import {LoginTotpComponent} from './pages/login-totp/login-totp.component';
|
|
||||||
import {FormLoginComponent} from './pages/form-login/form-login.component';
|
import {FormLoginComponent} from './pages/form-login/form-login.component';
|
||||||
import {FormLoginTotpComponent} from './pages/form-login-totp/form-login-totp.component';
|
import {FormLogin2FAComponent} from './pages/form-login-2fa/form-login-2fa.component';
|
||||||
import {TokensComponent} from './pages/tokens/tokens.component';
|
import {TokensComponent} from './pages/tokens/tokens.component';
|
||||||
import {InvitesComponent} from './pages/invites/invites.component';
|
import {InvitesComponent} from './pages/invites/invites.component';
|
||||||
import {PermissionsComponent} from './ui/permissions/permissions.component';
|
import {PermissionsComponent} from './ui/permissions/permissions.component';
|
||||||
@ -73,9 +72,8 @@ export class XhrInterceptor implements HttpInterceptor {
|
|||||||
ImprintComponent, PrivacyPolicyComponent, TermsOfServiceComponent,
|
ImprintComponent, PrivacyPolicyComponent, TermsOfServiceComponent,
|
||||||
AccountComponent,
|
AccountComponent,
|
||||||
LoginComponent,
|
LoginComponent,
|
||||||
LoginTotpComponent,
|
|
||||||
FormLoginComponent,
|
FormLoginComponent,
|
||||||
FormLoginTotpComponent,
|
FormLogin2FAComponent,
|
||||||
TokensComponent,
|
TokensComponent,
|
||||||
InvitesComponent,
|
InvitesComponent,
|
||||||
ServicesComponent,
|
ServicesComponent,
|
||||||
|
@ -1,25 +0,0 @@
|
|||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { AccountComponent } from './account.component';
|
|
||||||
|
|
||||||
describe('AccountComponent', () => {
|
|
||||||
let component: AccountComponent;
|
|
||||||
let fixture: ComponentFixture<AccountComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
declarations: [ AccountComponent ]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
fixture = TestBed.createComponent(AccountComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,25 +0,0 @@
|
|||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { AliasesComponent } from './aliases.component';
|
|
||||||
|
|
||||||
describe('AliasesComponent', () => {
|
|
||||||
let component: AliasesComponent;
|
|
||||||
let fixture: ComponentFixture<AliasesComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
declarations: [ AliasesComponent ]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
fixture = TestBed.createComponent(AliasesComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,25 +0,0 @@
|
|||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { DomainsComponent } from './domains.component';
|
|
||||||
|
|
||||||
describe('DomainsComponent', () => {
|
|
||||||
let component: DomainsComponent;
|
|
||||||
let fixture: ComponentFixture<DomainsComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
declarations: [ DomainsComponent ]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
fixture = TestBed.createComponent(DomainsComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,25 +0,0 @@
|
|||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { InfoComponent } from './info.component';
|
|
||||||
|
|
||||||
describe('InfoComponent', () => {
|
|
||||||
let component: InfoComponent;
|
|
||||||
let fixture: ComponentFixture<InfoComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
declarations: [ InfoComponent ]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
fixture = TestBed.createComponent(InfoComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,25 +0,0 @@
|
|||||||
import {ComponentFixture, TestBed} from '@angular/core/testing';
|
|
||||||
|
|
||||||
import {ProfileComponent} from './profile.component';
|
|
||||||
|
|
||||||
describe('ProfileComponent', () => {
|
|
||||||
let component: ProfileComponent;
|
|
||||||
let fixture: ComponentFixture<ProfileComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
declarations: [ProfileComponent]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
fixture = TestBed.createComponent(ProfileComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,25 +0,0 @@
|
|||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { SecurityComponent } from './security.component';
|
|
||||||
|
|
||||||
describe('SecurityComponent', () => {
|
|
||||||
let component: SecurityComponent;
|
|
||||||
let fixture: ComponentFixture<SecurityComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
declarations: [ SecurityComponent ]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
fixture = TestBed.createComponent(SecurityComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
@ -2,7 +2,7 @@ import {Component, OnInit, ViewChild, Inject} from '@angular/core';
|
|||||||
import {FormBuilder, FormGroup, FormControl, Validators, NgForm} from '@angular/forms';
|
import {FormBuilder, FormGroup, FormControl, Validators, NgForm} from '@angular/forms';
|
||||||
import {MatDialog, MatDialogRef, MAT_DIALOG_DATA} from '@angular/material/dialog';
|
import {MatDialog, MatDialogRef, MAT_DIALOG_DATA} from '@angular/material/dialog';
|
||||||
|
|
||||||
import {AuthService} from './../../../services/auth.service';
|
import {Auth2FAService} from './../../../services/auth.2fa.service';
|
||||||
import {UserService} from './../../../services/user.service';
|
import {UserService} from './../../../services/user.service';
|
||||||
import {MatchingValidator} from './../../../utils/matching.validator';
|
import {MatchingValidator} from './../../../utils/matching.validator';
|
||||||
|
|
||||||
@ -29,7 +29,7 @@ export class SecurityComponent implements OnInit {
|
|||||||
constructor(
|
constructor(
|
||||||
private formBuilder: FormBuilder,
|
private formBuilder: FormBuilder,
|
||||||
private userService: UserService,
|
private userService: UserService,
|
||||||
private authService: AuthService,
|
private auth2FAService: Auth2FAService,
|
||||||
public dialog: MatDialog) {}
|
public dialog: MatDialog) {}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
@ -52,7 +52,7 @@ export class SecurityComponent implements OnInit {
|
|||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
this.authService.isTotpEnabled().subscribe(response => {
|
this.auth2FAService.isEnabled('totp').subscribe(response => {
|
||||||
this.totp = true;
|
this.totp = true;
|
||||||
}, error => {
|
}, error => {
|
||||||
this.totp = false;
|
this.totp = false;
|
||||||
@ -99,7 +99,7 @@ export class SecurityComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
createTotp() {
|
createTotp() {
|
||||||
this.authService.createTotp().subscribe((result: any) => {
|
this.auth2FAService.create('totp').subscribe((result: any) => {
|
||||||
const dialogRef = this.dialog.open(SecurityTotpDialog, {
|
const dialogRef = this.dialog.open(SecurityTotpDialog, {
|
||||||
closeOnNavigation: false,
|
closeOnNavigation: false,
|
||||||
disableClose: true,
|
disableClose: true,
|
||||||
@ -108,11 +108,11 @@ export class SecurityComponent implements OnInit {
|
|||||||
|
|
||||||
dialogRef.afterClosed().subscribe(result => {
|
dialogRef.afterClosed().subscribe(result => {
|
||||||
if(result) {
|
if(result) {
|
||||||
this.authService.enableTotp(result).subscribe((result: any) => {
|
this.auth2FAService.enable('totp', result).subscribe((result: any) => {
|
||||||
this.totp = true;
|
this.totp = true;
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
this.authService.removeTotp().subscribe((result: any) => {
|
this.auth2FAService.remove('totp').subscribe((result: any) => {
|
||||||
this.totp = false;
|
this.totp = false;
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -130,7 +130,7 @@ export class SecurityComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
removeTotp() {
|
removeTotp() {
|
||||||
this.authService.removeTotp().subscribe((result: any) => {
|
this.auth2FAService.remove('totp').subscribe((result: any) => {
|
||||||
this.totp = false;
|
this.totp = false;
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -1,25 +0,0 @@
|
|||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { VoucherComponent } from './voucher.component';
|
|
||||||
|
|
||||||
describe('VoucherComponent', () => {
|
|
||||||
let component: VoucherComponent;
|
|
||||||
let fixture: ComponentFixture<VoucherComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
declarations: [ VoucherComponent ]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
fixture = TestBed.createComponent(VoucherComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
39
src/app/pages/form-login-2fa/form-login-2fa.component.html
Normal file
39
src/app/pages/form-login-2fa/form-login-2fa.component.html
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
<form action="{{apiUrl}}/auth/login/2fa" method="POST" #form2FA>
|
||||||
|
<mat-card>
|
||||||
|
<mat-card-content>
|
||||||
|
<h2>{{'security.2fa.external' | i18n}}<mat-icon style="font-size: 1em;">open_in_new
|
||||||
|
</mat-icon>
|
||||||
|
</h2>
|
||||||
|
<mat-error *ngIf="loginInvalid">
|
||||||
|
{{'security.2fa.invalid' | i18n}}
|
||||||
|
</mat-error>
|
||||||
|
<input id="provider" name="provider" matInput hidden [value]="selectedProvider.id">
|
||||||
|
<mat-select [(ngModel)]="selectedProvider" placeholder="{{'security.2fa.provider' | i18n}}"
|
||||||
|
[ngModelOptions]="{standalone: true}">
|
||||||
|
<mat-option *ngFor="let provider of providers" [value]="provider">
|
||||||
|
{{'security.2fa.' + provider.id | i18n}}
|
||||||
|
</mat-option>
|
||||||
|
</mat-select>
|
||||||
|
<a mat-raised-button (click)="request()"
|
||||||
|
*ngIf="selectedProvider && selectedProvider.request">{{'security.2fa.' + selectedProvider.id +
|
||||||
|
'.request'
|
||||||
|
| i18n}}</a>
|
||||||
|
<mat-form-field>
|
||||||
|
<input id="code" name="code" matInput placeholder="{{'security.2fa.code' | i18n}}" required
|
||||||
|
matAutofocus>
|
||||||
|
<mat-error>
|
||||||
|
{{'security.2fa.missing' | i18n}}
|
||||||
|
</mat-error>
|
||||||
|
</mat-form-field>
|
||||||
|
<mat-slide-toggle id="keep" name="keep" [checked]="keep">
|
||||||
|
{{'login.keepSession' | i18n}}
|
||||||
|
</mat-slide-toggle>
|
||||||
|
</mat-card-content>
|
||||||
|
<mat-card-actions>
|
||||||
|
<button type="submit" mat-raised-button color="primary" (click)="form2FA.submit()"
|
||||||
|
[disabled]="form2FA.invalid">{{'security.2fa.login' | i18n}}<mat-icon style="font-size: 1em;">
|
||||||
|
open_in_new
|
||||||
|
</mat-icon></button>
|
||||||
|
</mat-card-actions>
|
||||||
|
</mat-card>
|
||||||
|
</form>
|
@ -3,20 +3,25 @@ import {ActivatedRoute, Router} from '@angular/router';
|
|||||||
|
|
||||||
import {environment} from '../../../environments/environment';
|
import {environment} from '../../../environments/environment';
|
||||||
|
|
||||||
|
import {Auth2FAService} from '../../services/auth.2fa.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-form-login-totp',
|
selector: 'app-form-login-2fa',
|
||||||
templateUrl: './form-login-totp.component.html',
|
templateUrl: './form-login-2fa.component.html',
|
||||||
styleUrls: ['./form-login-totp.component.scss']
|
styleUrls: ['./form-login-2fa.component.scss']
|
||||||
})
|
})
|
||||||
export class FormLoginTotpComponent implements OnInit {
|
export class FormLogin2FAComponent implements OnInit {
|
||||||
|
|
||||||
loginInvalid: boolean;
|
loginInvalid: boolean;
|
||||||
keep: boolean = false;
|
keep: boolean = false;
|
||||||
apiUrl = environment.apiUrl;
|
apiUrl = environment.apiUrl;
|
||||||
|
selectedProvider = {id: "", request: false};
|
||||||
|
providers = [];
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private router: Router,
|
private router: Router,
|
||||||
private route: ActivatedRoute) {}
|
private route: ActivatedRoute,
|
||||||
|
private auth2FAService: Auth2FAService) {}
|
||||||
|
|
||||||
async ngOnInit() {
|
async ngOnInit() {
|
||||||
this.route.queryParams.subscribe(params => {
|
this.route.queryParams.subscribe(params => {
|
||||||
@ -29,8 +34,20 @@ export class FormLoginTotpComponent implements OnInit {
|
|||||||
this.router.navigate([], {queryParams: {keep: null}, queryParamsHandling: 'merge'});
|
this.router.navigate([], {queryParams: {keep: null}, queryParamsHandling: 'merge'});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.auth2FAService.getEnabled().subscribe((providers: any) => {
|
||||||
|
this.providers = providers;
|
||||||
|
if(this.providers[0]) {
|
||||||
|
this.selectedProvider = this.providers[0];
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
request() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
@ -1,27 +0,0 @@
|
|||||||
<form action="{{apiUrl}}/auth/login/totp" method="POST" #totpForm>
|
|
||||||
<mat-card>
|
|
||||||
<mat-card-content>
|
|
||||||
<h2>{{'security.2fa.totp.external' | i18n}}<mat-icon style="font-size: 1em;">open_in_new
|
|
||||||
</mat-icon>
|
|
||||||
</h2>
|
|
||||||
<mat-error *ngIf="loginInvalid">
|
|
||||||
{{'security.2fa.totp.invalid' | i18n}}
|
|
||||||
</mat-error>
|
|
||||||
<mat-form-field>
|
|
||||||
<input id="code" name="code" matInput placeholder="{{'security.2fa.totp.code' | i18n}}" required matAutofocus>
|
|
||||||
<mat-error>
|
|
||||||
{{'security.2fa.totp.missing' | i18n}}
|
|
||||||
</mat-error>
|
|
||||||
</mat-form-field>
|
|
||||||
<mat-slide-toggle id="keep" name="keep" [checked]="keep" >
|
|
||||||
{{'login.keepSession' | i18n}}
|
|
||||||
</mat-slide-toggle>
|
|
||||||
</mat-card-content>
|
|
||||||
<mat-card-actions>
|
|
||||||
<button type="submit" mat-raised-button color="primary" (click)="totpForm.submit()"
|
|
||||||
[disabled]="totpForm.invalid">{{'security.2fa.totp.login' | i18n}}<mat-icon style="font-size: 1em;">
|
|
||||||
open_in_new
|
|
||||||
</mat-icon></button>
|
|
||||||
</mat-card-actions>
|
|
||||||
</mat-card>
|
|
||||||
</form>
|
|
@ -1,25 +0,0 @@
|
|||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { FormLoginTotpComponent } from './form-login-totp.component';
|
|
||||||
|
|
||||||
describe('FormLoginTotpComponent', () => {
|
|
||||||
let component: FormLoginTotpComponent;
|
|
||||||
let fixture: ComponentFixture<FormLoginTotpComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
declarations: [ FormLoginTotpComponent ]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
fixture = TestBed.createComponent(FormLoginTotpComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,25 +0,0 @@
|
|||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { FormLoginComponent } from './form-login.component';
|
|
||||||
|
|
||||||
describe('FormLoginComponent', () => {
|
|
||||||
let component: FormLoginComponent;
|
|
||||||
let fixture: ComponentFixture<FormLoginComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
declarations: [ FormLoginComponent ]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
fixture = TestBed.createComponent(FormLoginComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,25 +0,0 @@
|
|||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { InvitesComponent } from './invites.component';
|
|
||||||
|
|
||||||
describe('InvitesComponent', () => {
|
|
||||||
let component: InvitesComponent;
|
|
||||||
let fixture: ComponentFixture<InvitesComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
declarations: [ InvitesComponent ]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
fixture = TestBed.createComponent(InvitesComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,25 +0,0 @@
|
|||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { JitsiComponent } from './jitsi.component';
|
|
||||||
|
|
||||||
describe('JitsiComponent', () => {
|
|
||||||
let component: JitsiComponent;
|
|
||||||
let fixture: ComponentFixture<JitsiComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
declarations: [ JitsiComponent ]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
fixture = TestBed.createComponent(JitsiComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,25 +0,0 @@
|
|||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { LoginTotpComponent } from './login-totp.component';
|
|
||||||
|
|
||||||
describe('LoginTotpComponent', () => {
|
|
||||||
let component: LoginTotpComponent;
|
|
||||||
let fixture: ComponentFixture<LoginTotpComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
declarations: [ LoginTotpComponent ]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
fixture = TestBed.createComponent(LoginTotpComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,9 +1,9 @@
|
|||||||
import { Component, OnInit } from '@angular/core';
|
import {Component, OnInit} from '@angular/core';
|
||||||
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
import {FormBuilder, FormGroup, Validators} from '@angular/forms';
|
||||||
import { AuthService } from '../../services/auth.service';
|
import {Auth2FAService} from '../../services/auth.2fa.service';
|
||||||
import { Router, ActivatedRoute } from '@angular/router';
|
import {Router, ActivatedRoute} from '@angular/router';
|
||||||
|
|
||||||
import { environment } from '../../../environments/environment';
|
import {environment} from '../../../environments/environment';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-login',
|
selector: 'app-login',
|
||||||
@ -17,7 +17,7 @@ export class LoginTotpComponent implements OnInit {
|
|||||||
public apiUrl = environment.apiUrl;
|
public apiUrl = environment.apiUrl;
|
||||||
targetRoute = '/account/info';
|
targetRoute = '/account/info';
|
||||||
|
|
||||||
constructor(private formBuilder: FormBuilder, private authService: AuthService, private router: Router, private route: ActivatedRoute) { }
|
constructor(private formBuilder: FormBuilder, private auth2FAService: Auth2FAService, private router: Router, private route: ActivatedRoute) {}
|
||||||
|
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
@ -27,7 +27,7 @@ export class LoginTotpComponent implements OnInit {
|
|||||||
});
|
});
|
||||||
|
|
||||||
this.route.queryParams.subscribe(params => {
|
this.route.queryParams.subscribe(params => {
|
||||||
if (params['target']) {
|
if(params['target']) {
|
||||||
this.targetRoute = params['target'];
|
this.targetRoute = params['target'];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -35,14 +35,8 @@ export class LoginTotpComponent implements OnInit {
|
|||||||
|
|
||||||
async loginTotp() {
|
async loginTotp() {
|
||||||
this.loginInvalid = false;
|
this.loginInvalid = false;
|
||||||
if (this.form.valid) {
|
if(this.form.valid) {
|
||||||
|
this.auth2FAService.login('totp', this.form.get('code').value, this.form.get('keep').value).subscribe((response: any) => {
|
||||||
const totpModel = {
|
|
||||||
code: this.form.get('code').value,
|
|
||||||
keep: this.form.get('keep').value
|
|
||||||
};
|
|
||||||
|
|
||||||
this.authService.loginTotp(totpModel).subscribe((response: any) => {
|
|
||||||
this.router.navigate([this.targetRoute]);
|
this.router.navigate([this.targetRoute]);
|
||||||
}, error => {
|
}, error => {
|
||||||
this.loginInvalid = true;
|
this.loginInvalid = true;
|
||||||
|
@ -1,25 +0,0 @@
|
|||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { LoginComponent } from './login.component';
|
|
||||||
|
|
||||||
describe('LoginComponent', () => {
|
|
||||||
let component: LoginComponent;
|
|
||||||
let fixture: ComponentFixture<LoginComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
declarations: [ LoginComponent ]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
fixture = TestBed.createComponent(LoginComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,25 +0,0 @@
|
|||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { NotfoundComponent } from './notfound.component';
|
|
||||||
|
|
||||||
describe('NotfoundComponent', () => {
|
|
||||||
let component: NotfoundComponent;
|
|
||||||
let fixture: ComponentFixture<NotfoundComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
declarations: [ NotfoundComponent ]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
fixture = TestBed.createComponent(NotfoundComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,25 +0,0 @@
|
|||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { PasswordResetComponent } from './password-reset.component';
|
|
||||||
|
|
||||||
describe('PasswordResetComponent', () => {
|
|
||||||
let component: PasswordResetComponent;
|
|
||||||
let fixture: ComponentFixture<PasswordResetComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
declarations: [ PasswordResetComponent ]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
fixture = TestBed.createComponent(PasswordResetComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,25 +0,0 @@
|
|||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { PasswordComponent } from './password.component';
|
|
||||||
|
|
||||||
describe('PasswordComponent', () => {
|
|
||||||
let component: PasswordComponent;
|
|
||||||
let fixture: ComponentFixture<PasswordComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
declarations: [ PasswordComponent ]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
fixture = TestBed.createComponent(PasswordComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,25 +0,0 @@
|
|||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { RegisterComponent } from './register.component';
|
|
||||||
|
|
||||||
describe('RegisterComponent', () => {
|
|
||||||
let component: RegisterComponent;
|
|
||||||
let fixture: ComponentFixture<RegisterComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
declarations: [ RegisterComponent ]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
fixture = TestBed.createComponent(RegisterComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,25 +0,0 @@
|
|||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { ServicesComponent } from './services.component';
|
|
||||||
|
|
||||||
describe('ServicesComponent', () => {
|
|
||||||
let component: ServicesComponent;
|
|
||||||
let fixture: ComponentFixture<ServicesComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
declarations: [ ServicesComponent ]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
fixture = TestBed.createComponent(ServicesComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,25 +0,0 @@
|
|||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { TokensComponent } from './tokens.component';
|
|
||||||
|
|
||||||
describe('TokensComponent', () => {
|
|
||||||
let component: TokensComponent;
|
|
||||||
let fixture: ComponentFixture<TokensComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
declarations: [ TokensComponent ]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
fixture = TestBed.createComponent(TokensComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,25 +0,0 @@
|
|||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { UnavailableComponent } from './unavailable.component';
|
|
||||||
|
|
||||||
describe('UnavailableComponent', () => {
|
|
||||||
let component: UnavailableComponent;
|
|
||||||
let fixture: ComponentFixture<UnavailableComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
declarations: [ UnavailableComponent ]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
fixture = TestBed.createComponent(UnavailableComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
@ -2,7 +2,7 @@
|
|||||||
<mat-progress-bar *ngIf="!success && !error" mode="indeterminate"></mat-progress-bar>
|
<mat-progress-bar *ngIf="!success && !error" mode="indeterminate"></mat-progress-bar>
|
||||||
|
|
||||||
<div *ngIf="success">
|
<div *ngIf="success">
|
||||||
<h3>{{model.username}}</h3>
|
<h3>{{model.username}} <small *ngIf="isMe">{{'user.isMe' | i18n}}</small></h3>
|
||||||
<app-profilefields [username]="model.username"></app-profilefields>
|
<app-profilefields [username]="model.username"></app-profilefields>
|
||||||
<div *ngIf="model.aliases && model.aliases.length > 0">
|
<div *ngIf="model.aliases && model.aliases.length > 0">
|
||||||
<h4>{{'user.aliases' | i18n}}</h4>
|
<h4>{{'user.aliases' | i18n}}</h4>
|
||||||
|
@ -1,25 +0,0 @@
|
|||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { UserComponent } from './user.component';
|
|
||||||
|
|
||||||
describe('UserComponent', () => {
|
|
||||||
let component: UserComponent;
|
|
||||||
let fixture: ComponentFixture<UserComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
declarations: [ UserComponent ]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
fixture = TestBed.createComponent(UserComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
@ -2,6 +2,7 @@ import {Component, OnInit} from '@angular/core';
|
|||||||
|
|
||||||
import {ActivatedRoute} from '@angular/router';
|
import {ActivatedRoute} from '@angular/router';
|
||||||
|
|
||||||
|
import {AuthService} from '../../services/auth.service';
|
||||||
import {ProfileService} from '../../services/profile.service';
|
import {ProfileService} from '../../services/profile.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@ -14,8 +15,10 @@ export class UserComponent implements OnInit {
|
|||||||
model: any;
|
model: any;
|
||||||
error = false;
|
error = false;
|
||||||
success = false;
|
success = false;
|
||||||
|
isMe = false;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
|
private authService: AuthService,
|
||||||
private profileService: ProfileService,
|
private profileService: ProfileService,
|
||||||
private route: ActivatedRoute) {}
|
private route: ActivatedRoute) {}
|
||||||
|
|
||||||
@ -27,6 +30,12 @@ export class UserComponent implements OnInit {
|
|||||||
}, error => {
|
}, error => {
|
||||||
this.error = error;
|
this.error = error;
|
||||||
})
|
})
|
||||||
|
|
||||||
|
this.authService.auth.subscribe((auth: any) => {
|
||||||
|
this.isMe = auth && auth.principal && auth.principal.username == this.username;
|
||||||
|
console.log(this.isMe, auth);
|
||||||
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
45
src/app/services/auth.2fa.service.ts
Normal file
45
src/app/services/auth.2fa.service.ts
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
import {Injectable} from '@angular/core';
|
||||||
|
import {HttpClient, HttpHeaders} from '@angular/common/http';
|
||||||
|
|
||||||
|
import {environment} from '../../environments/environment';
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root',
|
||||||
|
})
|
||||||
|
export class Auth2FAService {
|
||||||
|
|
||||||
|
constructor(private http: HttpClient) {
|
||||||
|
}
|
||||||
|
|
||||||
|
getEnabled() {
|
||||||
|
return this.http.get(environment.apiUrl + "/auth/2fa");
|
||||||
|
}
|
||||||
|
|
||||||
|
getAvailable() {
|
||||||
|
return this.http.get(environment.apiUrl + "/auth/2fa/available");
|
||||||
|
}
|
||||||
|
|
||||||
|
isEnabled(provider) {
|
||||||
|
return this.http.get(environment.apiUrl + "/auth/2fa/" + provider);
|
||||||
|
}
|
||||||
|
|
||||||
|
create(provider) {
|
||||||
|
return this.http.put(environment.apiUrl + "/auth/2fa/" + provider, {});
|
||||||
|
}
|
||||||
|
|
||||||
|
enable(provider, code) {
|
||||||
|
return this.http.patch(environment.apiUrl + "/auth/2fa/" + provider, code);
|
||||||
|
}
|
||||||
|
|
||||||
|
remove(provider) {
|
||||||
|
return this.http.delete(environment.apiUrl + "/auth/2fa/" + provider);
|
||||||
|
}
|
||||||
|
|
||||||
|
login(provider, code, keep) {
|
||||||
|
return this.http.post(environment.apiUrl + "/auth/login/2fa", {
|
||||||
|
'provider': provider,
|
||||||
|
'code': code,
|
||||||
|
'keep': keep
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -1,15 +1,15 @@
|
|||||||
import { Injectable } from '@angular/core';
|
import {Injectable} from '@angular/core';
|
||||||
import { BehaviorSubject, of } from 'rxjs';
|
import {ReplaySubject, of} from 'rxjs';
|
||||||
import { HttpClient, HttpHeaders } from '@angular/common/http';
|
import {HttpClient, HttpHeaders} from '@angular/common/http';
|
||||||
|
|
||||||
import { environment } from './../../environments/environment';
|
import {environment} from './../../environments/environment';
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root',
|
providedIn: 'root',
|
||||||
})
|
})
|
||||||
export class AuthService {
|
export class AuthService {
|
||||||
|
|
||||||
auth: BehaviorSubject<any> = new BehaviorSubject(undefined);
|
auth: ReplaySubject<any> = new ReplaySubject(undefined);
|
||||||
|
|
||||||
constructor(private http: HttpClient) {
|
constructor(private http: HttpClient) {
|
||||||
}
|
}
|
||||||
@ -37,31 +37,11 @@ export class AuthService {
|
|||||||
|
|
||||||
passwordRequest(username) {
|
passwordRequest(username) {
|
||||||
const headers = new HttpHeaders().set('Content-Type', 'text/plain; charset=utf-8');
|
const headers = new HttpHeaders().set('Content-Type', 'text/plain; charset=utf-8');
|
||||||
return this.http.post(environment.apiUrl + "/auth/password/request", username, { headers, responseType: 'text' });
|
return this.http.post(environment.apiUrl + "/auth/password/request", username, {headers, responseType: 'text'});
|
||||||
}
|
}
|
||||||
|
|
||||||
passwordReset(model) {
|
passwordReset(model) {
|
||||||
const headers = new HttpHeaders().set('Content-Type', 'text/plain; charset=utf-8');
|
const headers = new HttpHeaders().set('Content-Type', 'text/plain; charset=utf-8');
|
||||||
return this.http.post(environment.apiUrl + "/auth/password/reset", model);
|
return this.http.post(environment.apiUrl + "/auth/password/reset", model);
|
||||||
}
|
}
|
||||||
|
|
||||||
isTotpEnabled() {
|
|
||||||
return this.http.get(environment.apiUrl + "/auth/totp");
|
|
||||||
}
|
|
||||||
|
|
||||||
createTotp() {
|
|
||||||
return this.http.put(environment.apiUrl + "/auth/totp", {});
|
|
||||||
}
|
|
||||||
|
|
||||||
enableTotp(code) {
|
|
||||||
return this.http.patch(environment.apiUrl + "/auth/totp", code);
|
|
||||||
}
|
|
||||||
|
|
||||||
removeTotp() {
|
|
||||||
return this.http.delete(environment.apiUrl + "/auth/totp");
|
|
||||||
}
|
|
||||||
|
|
||||||
loginTotp(totpModel) {
|
|
||||||
return this.http.post(environment.apiUrl + "/auth/login/totp", totpModel);
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -1,25 +0,0 @@
|
|||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { PermissionsComponent } from './permissions.component';
|
|
||||||
|
|
||||||
describe('PermissionsComponent', () => {
|
|
||||||
let component: PermissionComponent;
|
|
||||||
let fixture: ComponentFixture<PermissionComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
declarations: [ PermissionsComponent ]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
fixture = TestBed.createComponent(PermissionsComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
@ -29,7 +29,7 @@ export class ProfileFieldPgpBlob implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.authService.getAuth().then((auth: any) => {
|
this.authService.auth.subscribe((auth: any) => {
|
||||||
if(!auth.authenticated) {
|
if(!auth.authenticated) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1,25 +0,0 @@
|
|||||||
import {ComponentFixture, TestBed} from '@angular/core/testing';
|
|
||||||
|
|
||||||
import {ProfileFieldsComponent} from './profilefields.component';
|
|
||||||
|
|
||||||
describe('ProfileFieldsComponent', () => {
|
|
||||||
let component: ProfileFieldsComponent;
|
|
||||||
let fixture: ComponentFixture<ProfileFieldsComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
declarations: [ProfileFieldsComponent]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
fixture = TestBed.createComponent(ProfileFieldsComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,25 +0,0 @@
|
|||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { QuotasComponent } from './quotas.component';
|
|
||||||
|
|
||||||
describe('QuotasComponent', () => {
|
|
||||||
let component: QuotasComponent;
|
|
||||||
let fixture: ComponentFixture<QuotasComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
declarations: [ QuotasComponent ]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
});
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
fixture = TestBed.createComponent(QuotasComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
@ -878,6 +878,117 @@
|
|||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
<h4 id="PeerTube">Nutzung des Dienstes PeerTube <small>tube.bstly.de</small></h4>
|
||||||
|
|
||||||
|
<h5>Gespeicherte Daten</h5>
|
||||||
|
|
||||||
|
<p>Die folgenden Daten werden durch den Dienst PeerTube erfasst:
|
||||||
|
<p>
|
||||||
|
|
||||||
|
<table border="1">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Bezeichnung</th>
|
||||||
|
<th>Betroffene Benutzer </th>
|
||||||
|
<th>Speicherfrist</th>
|
||||||
|
<th>Verwendungszweck</th>
|
||||||
|
<th>Weitergabe an Dritte</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<strong>Streaming-Daten / IP-Addresse</strong>
|
||||||
|
<p>P2P Video Funktionalität (<a href="https://tube.bstly.de/about/peertube#privacy">Details</a>)</p>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<p>Alle Nutzer der Plattform mit aktiviertem Verteilsystem (Standard)</p>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<p>Bis zum Leeren des Browser Caches</p>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<p>Teilen von geschauten Videos über P2P mit anderen.</p>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<p>Weitergabe an Dritte! Kann aktiv ausgeschaltet werden.</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<strong>Account-Daten</strong>
|
||||||
|
<p>Benutzername, E-Mail Adresse, Profildaten (freiwillig)</p>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<p>Benutzer mit Account</p>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<p>bis zur Löschung</p>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<p>Erstellen von Kanälen, Videos, Livestreams und Kommentaren.</p>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<p>einsehbar für andere Benutzer</p>
|
||||||
|
<p>öffentlich einsehbar bei Aktivitäten in öffentlichen Kanälen</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<strong>Einstellungen/Kanäle</strong>
|
||||||
|
<p>Eigene, favorisierte Kanäle</p>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<p>Benutzer mit Account</p>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<p>bis zur Löschung</p>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<p>Verwaltung der Kanälen, Nutzung der Plattform</p>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<p>Weitergabe individuell vom Nutzer einstellbar</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<strong>Videos/Livestreams</strong>
|
||||||
|
<p>Videos in den Kanälen</p>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<p>Benutzer mit Account</p>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<p>siehe Einstellungen/Kanäle</p>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<p>Hochladen von Videos in Kanäle, Bereitstellen der Videos für andere, Livestreams</p>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<p>Abhängig von Sichtbarkeit der entsprechenden Kanäle/Videos/Livestreams, siehe Einstellungen/Kanäle</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<strong>Kommentare</strong>
|
||||||
|
<p>Kommentare zu Videos</p>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<p>Benutzer mit Account</p>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<p>siehe Einstellungen/ Kanäle</p>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<p>Kommunikation über Inhalte</p>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<p>Abhängig von Sichtbarkeit der entsprechenden Kanäle/Videos, siehe Einstellungen/Kanäle</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
<h4 id="Gitea">Nutzung des Dienstes Gitea <small>git.bstly.de</small></h4>
|
<h4 id="Gitea">Nutzung des Dienstes Gitea <small>git.bstly.de</small></h4>
|
||||||
|
|
||||||
@ -918,7 +1029,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<strong>Einstellungen/ Repositorien</strong>
|
<strong>Einstellungen/Repositorien</strong>
|
||||||
<p>Eigene, favorisierte Repositorien, Öffentlicher Schlüssel zur Authentifizierung </p>
|
<p>Eigene, favorisierte Repositorien, Öffentlicher Schlüssel zur Authentifizierung </p>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
@ -943,13 +1054,13 @@
|
|||||||
<p>Benutzer mit Account</p>
|
<p>Benutzer mit Account</p>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<p>siehe Einstellungen/ Repositorien</p>
|
<p>siehe Einstellungen/Repositorien</p>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<p>Speichern von Dateien in Repositorien</p>
|
<p>Speichern von Dateien in Repositorien</p>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<p>Abhängig von Sichtbarkeit der entsprechenden Repositorien, siehe Einstellungen/ Repositorien</p>
|
<p>Abhängig von Sichtbarkeit der entsprechenden Repositorien, siehe Einstellungen/Repositorien</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
@ -961,13 +1072,13 @@
|
|||||||
<p>Benutzer mit Account</p>
|
<p>Benutzer mit Account</p>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<p>siehe Einstellungen/ Repositorien</p>
|
<p>siehe Einstellungen/Repositorien</p>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<p>Nachverfolgung und Wiederherstellung von Änderungen</p>
|
<p>Nachverfolgung und Wiederherstellung von Änderungen</p>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<p>Abhängig von Sichtbarkeit der entsprechenden Repositorien, siehe Einstellungen/ Repositorien</p>
|
<p>Abhängig von Sichtbarkeit der entsprechenden Repositorien, siehe Einstellungen/Repositorien</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
@ -979,13 +1090,13 @@
|
|||||||
<p>Benutzer mit Account</p>
|
<p>Benutzer mit Account</p>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<p>siehe Einstellungen/ Repositorien</p>
|
<p>siehe Einstellungen/Repositorien</p>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<p>Dokumentation, Aufgabenmanagement und Kommunikation über Inhalte</p>
|
<p>Dokumentation, Aufgabenmanagement und Kommunikation über Inhalte</p>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<p>Abhängig von Sichtbarkeit der entsprechenden Repositorien, siehe Einstellungen/ Repositorien</p>
|
<p>Abhängig von Sichtbarkeit der entsprechenden Repositorien, siehe Einstellungen/Repositorien</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
@ -880,6 +880,117 @@
|
|||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
<h4 id="PeerTube">Nutzung des Dienstes PeerTube <small>tube.bstly.de</small></h4>
|
||||||
|
|
||||||
|
<h5>Gespeicherte Daten</h5>
|
||||||
|
|
||||||
|
<p>Die folgenden Daten werden durch den Dienst PeerTube erfasst:
|
||||||
|
<p>
|
||||||
|
|
||||||
|
<table border="1">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Bezeichnung</th>
|
||||||
|
<th>Betroffene Benutzer </th>
|
||||||
|
<th>Speicherfrist</th>
|
||||||
|
<th>Verwendungszweck</th>
|
||||||
|
<th>Weitergabe an Dritte</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<strong>Streaming-Daten / IP-Addresse</strong>
|
||||||
|
<p>P2P Video Funktionalität (<a href="https://tube.bstly.de/about/peertube#privacy">Details</a>)</p>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<p>Alle Nutzer der Plattform mit aktiviertem Verteilsystem (Standard)</p>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<p>Bis zum Leeren des Browser Caches</p>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<p>Teilen von geschauten Videos über P2P mit anderen.</p>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<p>Weitergabe an Dritte! Kann aktiv ausgeschaltet werden.</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<strong>Account-Daten</strong>
|
||||||
|
<p>Benutzername, E-Mail Adresse, Profildaten (freiwillig)</p>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<p>Benutzer mit Account</p>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<p>bis zur Löschung</p>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<p>Erstellen von Kanälen, Videos, Livestreams und Kommentaren.</p>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<p>einsehbar für andere Benutzer</p>
|
||||||
|
<p>öffentlich einsehbar bei Aktivitäten in öffentlichen Kanälen</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<strong>Einstellungen/Kanäle</strong>
|
||||||
|
<p>Eigene, favorisierte Kanäle</p>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<p>Benutzer mit Account</p>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<p>bis zur Löschung</p>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<p>Verwaltung der Kanälen, Nutzung der Plattform</p>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<p>Weitergabe individuell vom Nutzer einstellbar</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<strong>Videos/Livestreams</strong>
|
||||||
|
<p>Videos in den Kanälen</p>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<p>Benutzer mit Account</p>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<p>siehe Einstellungen/Kanäle</p>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<p>Hochladen von Videos in Kanäle, Bereitstellen der Videos für andere, Livestreams</p>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<p>Abhängig von Sichtbarkeit der entsprechenden Kanäle/Videos/Livestreams, siehe Einstellungen/Kanäle</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<strong>Kommentare</strong>
|
||||||
|
<p>Kommentare zu Videos</p>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<p>Benutzer mit Account</p>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<p>siehe Einstellungen/ Kanäle</p>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<p>Kommunikation über Inhalte</p>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<p>Abhängig von Sichtbarkeit der entsprechenden Kanäle/Videos, siehe Einstellungen/Kanäle</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
<h4 id="Gitea">Nutzung des Dienstes Gitea <small>git.bstly.de</small></h4>
|
<h4 id="Gitea">Nutzung des Dienstes Gitea <small>git.bstly.de</small></h4>
|
||||||
|
|
||||||
@ -920,7 +1031,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<strong>Einstellungen/ Repositorien</strong>
|
<strong>Einstellungen/Repositorien</strong>
|
||||||
<p>Eigene, favorisierte Repositorien, Öffentlicher Schlüssel zur Authentifizierung </p>
|
<p>Eigene, favorisierte Repositorien, Öffentlicher Schlüssel zur Authentifizierung </p>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
@ -945,13 +1056,13 @@
|
|||||||
<p>Benutzer mit Account</p>
|
<p>Benutzer mit Account</p>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<p>siehe Einstellungen/ Repositorien</p>
|
<p>siehe Einstellungen/Repositorien</p>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<p>Speichern von Dateien in Repositorien</p>
|
<p>Speichern von Dateien in Repositorien</p>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<p>Abhängig von Sichtbarkeit der entsprechenden Repositorien, siehe Einstellungen/ Repositorien</p>
|
<p>Abhängig von Sichtbarkeit der entsprechenden Repositorien, siehe Einstellungen/Repositorien</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
@ -963,13 +1074,13 @@
|
|||||||
<p>Benutzer mit Account</p>
|
<p>Benutzer mit Account</p>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<p>siehe Einstellungen/ Repositorien</p>
|
<p>siehe Einstellungen/Repositorien</p>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<p>Nachverfolgung und Wiederherstellung von Änderungen</p>
|
<p>Nachverfolgung und Wiederherstellung von Änderungen</p>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<p>Abhängig von Sichtbarkeit der entsprechenden Repositorien, siehe Einstellungen/ Repositorien</p>
|
<p>Abhängig von Sichtbarkeit der entsprechenden Repositorien, siehe Einstellungen/Repositorien</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
@ -981,13 +1092,13 @@
|
|||||||
<p>Benutzer mit Account</p>
|
<p>Benutzer mit Account</p>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<p>siehe Einstellungen/ Repositorien</p>
|
<p>siehe Einstellungen/Repositorien</p>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<p>Dokumentation, Aufgabenmanagement und Kommunikation über Inhalte</p>
|
<p>Dokumentation, Aufgabenmanagement und Kommunikation über Inhalte</p>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<p>Abhängig von Sichtbarkeit der entsprechenden Repositorien, siehe Einstellungen/ Repositorien</p>
|
<p>Abhängig von Sichtbarkeit der entsprechenden Repositorien, siehe Einstellungen/Repositorien</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
Loading…
Reference in New Issue
Block a user