Add auth module.
This commit is contained in:
parent
414b9eb215
commit
65f3dae4b1
1
src/app/auth/_directives/index.ts
Normal file
1
src/app/auth/_directives/index.ts
Normal file
@ -0,0 +1 @@
|
||||
// export * from 'password-toggle.directive';
|
@ -0,0 +1,8 @@
|
||||
import { PasswordToggleDirective } from './password-toggle.directive';
|
||||
|
||||
describe('PasswordToggleDirective', () => {
|
||||
it('should create an instance', () => {
|
||||
const directive = new PasswordToggleDirective();
|
||||
expect(directive).toBeTruthy();
|
||||
});
|
||||
});
|
38
src/app/auth/_directives/password-toggle.directive.ts
Normal file
38
src/app/auth/_directives/password-toggle.directive.ts
Normal file
@ -0,0 +1,38 @@
|
||||
import {Directive, ElementRef, Input, Renderer2} from '@angular/core';
|
||||
|
||||
@Directive({
|
||||
selector: '[appPasswordToggle]'
|
||||
})
|
||||
export class PasswordToggleDirective {
|
||||
@Input()
|
||||
id: string;
|
||||
|
||||
@Input()
|
||||
iconId: string;
|
||||
|
||||
constructor(
|
||||
private elementRef: ElementRef,
|
||||
private renderer: Renderer2,
|
||||
) {
|
||||
this.renderer.listen(this.elementRef.nativeElement, 'click', () => {
|
||||
this.togglePasswordVisibility();
|
||||
});
|
||||
}
|
||||
|
||||
togglePasswordVisibility(): void {
|
||||
const password = document.getElementById(this.id);
|
||||
const icon = document.getElementById(this.iconId);
|
||||
// @ts-ignore
|
||||
if (password.type === 'password') {
|
||||
// @ts-ignore
|
||||
password.type = 'text';
|
||||
icon.classList.remove('fa-eye');
|
||||
icon.classList.add('fa-eye-slash');
|
||||
} else {
|
||||
// @ts-ignore
|
||||
password.type = 'password';
|
||||
icon.classList.remove('fa-eye-slash');
|
||||
icon.classList.add('fa-eye');
|
||||
}
|
||||
}
|
||||
}
|
56
src/app/auth/add-key/add-key.component.html
Normal file
56
src/app/auth/add-key/add-key.component.html
Normal file
@ -0,0 +1,56 @@
|
||||
<div class="container">
|
||||
<div class="row justify-content-center mt-5 mb-5">
|
||||
<div class="col-lg-6 col-md-8 col-sm-10">
|
||||
<div class="card">
|
||||
<mat-card-title class="card-header pt-4 pb-4 text-center bg-dark">
|
||||
<a routerLink="/">
|
||||
<h1 class="text-white">CICADA</h1>
|
||||
</a>
|
||||
</mat-card-title>
|
||||
<div id="one" style="display: block" class="card-body p-4">
|
||||
|
||||
<div class="text-center w-75 m-auto">
|
||||
<h4 class="text-dark-50 text-center font-weight-bold">Add Private Key</h4>
|
||||
</div>
|
||||
|
||||
<form [formGroup]="keyForm" (ngSubmit)="onSubmit()">
|
||||
|
||||
<mat-form-field appearance="outline" class="full-width">
|
||||
<mat-label>Private Key</mat-label>
|
||||
<textarea matInput style="height: 30rem" name="privateKeyAsc" id="privateKeyAsc" formControlName="key"
|
||||
placeholder="Enter your private key..." [errorStateMatcher]="matcher"></textarea>
|
||||
<mat-error *ngIf="keyFormStub.key.errors.required">Private Key is required.</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<button mat-raised-button matRipple color="primary" type="submit" [disabled]="loading">
|
||||
<span *ngIf="loading" class="spinner-border spinner-border-sm mr-1"></span>
|
||||
Add Key
|
||||
</button>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
<div id="two" style="display: none" class="card-body p-4">
|
||||
|
||||
<div class="text-center w-75 m-auto">
|
||||
<h4 class="text-dark-50 text-center font-weight-bold">Enter Passphrase</h4>
|
||||
</div>
|
||||
|
||||
<form [formGroup]="passphraseForm" (ngSubmit)="login()">
|
||||
|
||||
<mat-form-field appearance="outline" class="full-width">
|
||||
<mat-label>Passphrase</mat-label>
|
||||
<input matInput name="state" id="state" formControlName="passphrase"
|
||||
placeholder="Enter your passphrase..." [errorStateMatcher]="matcher">
|
||||
<mat-error *ngIf="passphraseFormStub.passphrase.errors.required">Passphrase is required.</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<button mat-raised-button matRipple color="primary" type="submit" [disabled]="loading">
|
||||
<span *ngIf="loading" class="spinner-border spinner-border-sm mr-1"></span>
|
||||
Login
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
0
src/app/auth/add-key/add-key.component.scss
Normal file
0
src/app/auth/add-key/add-key.component.scss
Normal file
25
src/app/auth/add-key/add-key.component.spec.ts
Normal file
25
src/app/auth/add-key/add-key.component.spec.ts
Normal file
@ -0,0 +1,25 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { AddKeyComponent } from './add-key.component';
|
||||
|
||||
describe('AddKeyComponent', () => {
|
||||
let component: AddKeyComponent;
|
||||
let fixture: ComponentFixture<AddKeyComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ AddKeyComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(AddKeyComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
64
src/app/auth/add-key/add-key.component.ts
Normal file
64
src/app/auth/add-key/add-key.component.ts
Normal file
@ -0,0 +1,64 @@
|
||||
import {AfterViewInit, Component, OnInit, Renderer2} from '@angular/core';
|
||||
import {FormBuilder, FormGroup, Validators} from '@angular/forms';
|
||||
import {CustomErrorStateMatcher} from '../../_helpers';
|
||||
import {AuthService} from '../../_services';
|
||||
|
||||
@Component({
|
||||
selector: 'app-add-key',
|
||||
templateUrl: './add-key.component.html',
|
||||
styleUrls: ['./add-key.component.scss']
|
||||
})
|
||||
export class AddKeyComponent implements OnInit, AfterViewInit {
|
||||
keyForm: FormGroup;
|
||||
passphraseForm: FormGroup;
|
||||
submitted: boolean = false;
|
||||
loading: boolean = false;
|
||||
matcher = new CustomErrorStateMatcher();
|
||||
|
||||
constructor(
|
||||
private authService: AuthService,
|
||||
private formBuilder: FormBuilder,
|
||||
private renderer: Renderer2
|
||||
) { }
|
||||
|
||||
ngAfterViewInit(): void {
|
||||
console.debug(window.location);
|
||||
const xhr = new XMLHttpRequest();
|
||||
xhr.responseType = 'text';
|
||||
xhr.open('GET', window.location.origin + '/privatekey.asc');
|
||||
xhr.onload = (e) => {
|
||||
if (xhr.status !== 200) {
|
||||
console.warn('failed to autoload private key ciphertext');
|
||||
return;
|
||||
}
|
||||
(document.getElementById('privateKeyAsc') as HTMLInputElement).value = xhr.responseText;
|
||||
};
|
||||
xhr.send();
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.keyForm = this.formBuilder.group({
|
||||
key: ['', Validators.required],
|
||||
});
|
||||
this.passphraseForm = this.formBuilder.group({
|
||||
passphrase: ['', Validators.required],
|
||||
});
|
||||
}
|
||||
|
||||
get keyFormStub(): any { return this.keyForm.controls; }
|
||||
get passphraseFormStub(): any { return this.passphraseForm.controls; }
|
||||
|
||||
onSubmit(): void {
|
||||
this.submitted = true;
|
||||
|
||||
if (this.keyForm.invalid) { return; }
|
||||
|
||||
this.loading = true;
|
||||
this.authService.setKey(this.keyFormStub.key.value).then();
|
||||
}
|
||||
|
||||
login(): void {
|
||||
if (this.passphraseForm.invalid) { return; }
|
||||
this.authService.login();
|
||||
}
|
||||
}
|
16
src/app/auth/auth-routing.module.ts
Normal file
16
src/app/auth/auth-routing.module.ts
Normal file
@ -0,0 +1,16 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { Routes, RouterModule } from '@angular/router';
|
||||
|
||||
import { AuthComponent } from './auth.component';
|
||||
import {AddKeyComponent} from './add-key/add-key.component';
|
||||
|
||||
const routes: Routes = [
|
||||
{ path: '', component: AuthComponent },
|
||||
{ path: 'key', component: AddKeyComponent },
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports: [RouterModule.forChild(routes)],
|
||||
exports: [RouterModule]
|
||||
})
|
||||
export class AuthRoutingModule { }
|
99
src/app/auth/auth.component.html
Normal file
99
src/app/auth/auth.component.html
Normal file
@ -0,0 +1,99 @@
|
||||
<div class="container">
|
||||
<div class="row justify-content-center mt-5 mb-5">
|
||||
<div class="col-lg-6 col-md-8 col-sm-10">
|
||||
<div class="card">
|
||||
<!-- Logo-->
|
||||
<div class="card-header pt-4 pb-4 text-center bg-dark">
|
||||
<a routerLink="/">
|
||||
<!-- <span><img src="assets/images/logo.png" alt="" height="18"></span>-->
|
||||
<h1 class="text-white">CIC CLIENT</h1>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="card-body p-4">
|
||||
|
||||
<div class="text-center w-75 m-auto">
|
||||
<h4 class="text-dark-50 text-center mt-0 font-weight-bold">Sign Up</h4>
|
||||
</div>
|
||||
|
||||
<form [formGroup]="registerForm" (ngSubmit)="onSubmit()">
|
||||
|
||||
<div class="form-group">
|
||||
<label for="emailaddress">Email address</label>
|
||||
<input class="form-control" type="email" id="emailaddress" required placeholder="Enter your email" formControlName="email" [ngClass]="{ 'is-invalid': submitted && form.email.errors }">
|
||||
<div *ngIf="submitted && form.email.errors" class="invalid-feedback">
|
||||
<div *ngIf="form.email.errors.required">Email is required</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="password">Password</label>
|
||||
<div class="input-group input-group-merge">
|
||||
<input type="password" id="password" class="form-control" placeholder="Enter your password" formControlName="password" [ngClass]="{ 'is-invalid': submitted && form.password.errors }" required>
|
||||
<div class="input-group-append" data-password="false" appPasswordToggle [id]="'password'" [iconId]="'icon'">
|
||||
<div class="input-group-text">
|
||||
<span id="icon" class="fa fa-eye"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div *ngIf="submitted && form.password.errors" class="invalid-feedback">
|
||||
<div *ngIf="form.password.errors.required">Password is required</div>
|
||||
<div *ngIf="form.password.errors.hasCapitalCase">Should contain at least 1 uppercase alphabet</div>
|
||||
<div *ngIf="form.password.errors.hasSmallCase">Should contain at least 1 lowercase alphabet</div>
|
||||
<div *ngIf="form.password.errors.hasNumber">Should contain at least 1 number</div>
|
||||
<div *ngIf="form.password.errors.minlength">Should be at least 8 characters</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="confirmPassword">Confirm Password</label>
|
||||
<div class="input-group input-group-merge">
|
||||
<input type="password" id="confirmPassword" class="form-control" placeholder="Enter your password" formControlName="confirmPasword" [ngClass]="{ 'is-invalid': submitted && form.confirmPassword.errors }" required>
|
||||
<div class="input-group-append" data-password="false">
|
||||
<div class="input-group-text" appPasswordToggle [id]="'confirmPassword'" [iconId]="'icon2'">
|
||||
<span id="icon2" class="fa fa-eye"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div *ngIf="submitted && form.confirmPassword.errors" class="invalid-feedback">
|
||||
<div *ngIf="form.confirmPassword.errors.required">Password is required</div>
|
||||
<div *ngIf="form.confirmPassword.errors.NoPasswordMatch">Your passwords do not match</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="custom-control custom-checkbox">
|
||||
<input type="checkbox" class="custom-control-input" id="checkbox-signup" formControlName="terms" [ngClass]="{ 'is-invalid': submitted && form.terms.errors }" required>
|
||||
<label class="custom-control-label" for="checkbox-signup">I accept <a href="#" class="text-muted">Terms and Conditions</a></label>
|
||||
<div *ngIf="submitted && form.terms.errors" class="invalid-feedback">
|
||||
<div *ngIf="form.terms.errors.required">Accept terms and conditions to continue!</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group mb-0 text-center">
|
||||
<button matRipple mat-raised-button color="primary" type="submit" [disabled]="loading">
|
||||
<span *ngIf="loading" class="spinner-border spinner-border-sm mr-1"></span>
|
||||
Sign Up
|
||||
</button>
|
||||
</div>
|
||||
<div *ngIf="error" class="alert alert-danger mt-3 mb-0">{{ error }}</div>
|
||||
|
||||
</form>
|
||||
</div> <!-- end card-body -->
|
||||
</div>
|
||||
<!-- end card -->
|
||||
|
||||
<div class="row mt-3">
|
||||
<div class="col-12 text-center">
|
||||
<p class="text-muted">Already have account? <a routerLink="/auth" class="text-muted ml-1"><b>Log In</b></a></p>
|
||||
</div> <!-- end col-->
|
||||
</div>
|
||||
<!-- end row -->
|
||||
|
||||
</div> <!-- end col -->
|
||||
</div>
|
||||
<!-- end row -->
|
||||
</div>
|
||||
<!-- end container -->
|
||||
<!--<app-footer></app-footer>-->
|
0
src/app/auth/auth.component.scss
Normal file
0
src/app/auth/auth.component.scss
Normal file
25
src/app/auth/auth.component.spec.ts
Normal file
25
src/app/auth/auth.component.spec.ts
Normal file
@ -0,0 +1,25 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { AuthComponent } from './auth.component';
|
||||
|
||||
describe('AuthComponent', () => {
|
||||
let component: AuthComponent;
|
||||
let fixture: ComponentFixture<AuthComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ AuthComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(AuthComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
51
src/app/auth/auth.component.ts
Normal file
51
src/app/auth/auth.component.ts
Normal file
@ -0,0 +1,51 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import {FormBuilder, FormGroup, Validators} from '@angular/forms';
|
||||
import {CustomValidator} from '../_helpers';
|
||||
|
||||
@Component({
|
||||
selector: 'app-auth',
|
||||
templateUrl: './auth.component.html',
|
||||
styleUrls: ['./auth.component.scss']
|
||||
})
|
||||
export class AuthComponent implements OnInit {
|
||||
registerForm: FormGroup;
|
||||
submitted: boolean = false;
|
||||
loading: boolean = false;
|
||||
error: any;
|
||||
|
||||
constructor(
|
||||
private formBuilder: FormBuilder,
|
||||
) { }
|
||||
|
||||
ngOnInit(): void {
|
||||
this.registerForm = this.formBuilder.group({
|
||||
email: ['', Validators.required],
|
||||
password: ['', [
|
||||
// 1. Password Field is Required
|
||||
Validators.required,
|
||||
// 2. check whether the entered password has a number
|
||||
CustomValidator.patternValidator(/\d/, { hasNumber: true }),
|
||||
// 3. check whether the entered password has upper case letter
|
||||
CustomValidator.patternValidator(/[A-Z]/, { hasCapitalCase: true }),
|
||||
// 4. check whether the entered password has a lower-case letter
|
||||
CustomValidator.patternValidator(/[a-z]/, { hasSmallCase: true }),
|
||||
// 6. Has a minimum length of 8 characters
|
||||
Validators.minLength(8)]],
|
||||
confirmPassword: ['', Validators.required],
|
||||
terms: ['', Validators.required]
|
||||
}, {
|
||||
// validator for the form group
|
||||
validator: CustomValidator.passwordMatchValidator
|
||||
});
|
||||
}
|
||||
|
||||
get form(): any { return this.registerForm.controls; }
|
||||
|
||||
onSubmit(): void {
|
||||
this.submitted = true;
|
||||
|
||||
if (this.registerForm.invalid) { return; }
|
||||
|
||||
this.loading = true;
|
||||
}
|
||||
}
|
31
src/app/auth/auth.module.ts
Normal file
31
src/app/auth/auth.module.ts
Normal file
@ -0,0 +1,31 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
|
||||
import { AuthRoutingModule } from './auth-routing.module';
|
||||
import { AuthComponent } from './auth.component';
|
||||
import {ReactiveFormsModule} from '@angular/forms';
|
||||
import {PasswordToggleDirective} from './_directives/password-toggle.directive';
|
||||
import { AddKeyComponent } from './add-key/add-key.component';
|
||||
import {MatCardModule} from '@angular/material/card';
|
||||
import {MatSelectModule} from '@angular/material/select';
|
||||
import {MatInputModule} from '@angular/material/input';
|
||||
import {MatButtonModule} from '@angular/material/button';
|
||||
import {MatRippleModule} from '@angular/material/core';
|
||||
// import {PasswordToggleDirective} from '../_directives/password-toggle.directive';
|
||||
|
||||
|
||||
@NgModule({
|
||||
declarations: [AuthComponent, PasswordToggleDirective, AddKeyComponent],
|
||||
imports: [
|
||||
CommonModule,
|
||||
AuthRoutingModule,
|
||||
ReactiveFormsModule,
|
||||
MatCardModule,
|
||||
MatSelectModule,
|
||||
MatInputModule,
|
||||
MatButtonModule,
|
||||
MatRippleModule,
|
||||
// PasswordToggleDirective
|
||||
]
|
||||
})
|
||||
export class AuthModule { }
|
Loading…
Reference in New Issue
Block a user