refactored to prepare for adding logout functionality
parent
c037b77387
commit
fedb8e7c6a
|
@ -0,0 +1,18 @@
|
|||
import { NgModule } from '@angular/core';
|
||||
import { Routes, RouterModule } from '@angular/router';
|
||||
|
||||
import { LoginComponent } from "./login/login.component";
|
||||
// import { PageNotFoundComponent } from "./page-not-found/page-not-found.component";
|
||||
|
||||
const routes: Routes = [
|
||||
{ path: 'login', component: LoginComponent },
|
||||
// { path: '', redirectTo: '/login', pathMatch: 'full' },
|
||||
// { path: '**', component: PageNotFoundComponent }
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports: [ RouterModule.forRoot(routes) ],
|
||||
exports: [ RouterModule ]
|
||||
})
|
||||
export class AppRoutingModule {
|
||||
}
|
|
@ -8,24 +8,5 @@ This condition is temporary it should be removed when the social login logic
|
|||
is refactored and moved into Selene.
|
||||
-->
|
||||
<div *ngIf="!socialLoginDataFound">
|
||||
<div class="split top"></div>
|
||||
<div class="split bottom"></div>
|
||||
<div fxLayout="column" fxLayoutAlign="center center">
|
||||
<div align="center">
|
||||
<img src="../../assets/mycroft-ai-no-logo.svg"/>
|
||||
</div>
|
||||
<div class="login-options">
|
||||
<login-authenticate></login-authenticate>
|
||||
<!--<mat-tab-group>-->
|
||||
<!--<mat-tab label="LOG IN">-->
|
||||
<!--<login-authenticate></login-authenticate>-->
|
||||
<!--</mat-tab>-->
|
||||
<!--<mat-tab label="SIGN UP">-->
|
||||
<!--<login-auth-social></login-auth-social>-->
|
||||
<!--<div class="mat-subheading-2">OR</div>-->
|
||||
<!--<login-auth-antisocial></login-auth-antisocial>-->
|
||||
<!--</mat-tab>-->
|
||||
<!--</mat-tab-group>-->
|
||||
</div>
|
||||
</div>
|
||||
<router-outlet></router-outlet>
|
||||
</div>
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
import { TestBed, async } from '@angular/core/testing';
|
||||
import { AppComponent } from './app.component';
|
||||
describe('AppComponent', () => {
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [
|
||||
AppComponent
|
||||
],
|
||||
}).compileComponents();
|
||||
}));
|
||||
it('should create the app', async(() => {
|
||||
const fixture = TestBed.createComponent(AppComponent);
|
||||
const app = fixture.debugElement.componentInstance;
|
||||
expect(app).toBeTruthy();
|
||||
}));
|
||||
it(`should have as title 'app'`, async(() => {
|
||||
const fixture = TestBed.createComponent(AppComponent);
|
||||
const app = fixture.debugElement.componentInstance;
|
||||
expect(app.title).toEqual('app');
|
||||
}));
|
||||
it('should render title in a h1 tag', async(() => {
|
||||
const fixture = TestBed.createComponent(AppComponent);
|
||||
fixture.detectChanges();
|
||||
const compiled = fixture.debugElement.nativeElement;
|
||||
expect(compiled.querySelector('h1').textContent).toContain('Welcome to frontend!');
|
||||
}));
|
||||
});
|
|
@ -16,7 +16,7 @@ export class AppComponent implements OnInit {
|
|||
ngOnInit () {
|
||||
let uriParams = decodeURIComponent(window.location.search);
|
||||
|
||||
if (uriParams) {
|
||||
if (!window.location.pathname && uriParams) {
|
||||
this.socialLoginDataFound = true;
|
||||
window.opener.postMessage(uriParams, window.location.origin);
|
||||
window.close();
|
||||
|
|
|
@ -4,15 +4,17 @@ import { FlexLayoutModule } from "@angular/flex-layout";
|
|||
import { NgModule } from '@angular/core';
|
||||
|
||||
import { AppComponent } from './app.component';
|
||||
import { AuthModule } from "./auth/auth.module";
|
||||
import { AppRoutingModule } from "./app-routing.module";
|
||||
import { LoginModule } from "./login/login.module";
|
||||
|
||||
@NgModule({
|
||||
declarations: [ AppComponent ],
|
||||
imports: [
|
||||
BrowserModule,
|
||||
AuthModule,
|
||||
LoginModule,
|
||||
BrowserAnimationsModule,
|
||||
FlexLayoutModule
|
||||
FlexLayoutModule,
|
||||
AppRoutingModule
|
||||
],
|
||||
providers: [ ],
|
||||
bootstrap: [ AppComponent ]
|
||||
|
|
|
@ -1,75 +0,0 @@
|
|||
@import '../../stylesheets/global';
|
||||
|
||||
button {
|
||||
@include login-button;
|
||||
}
|
||||
|
||||
.social {
|
||||
padding: 20px;
|
||||
button {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
fa-icon {
|
||||
margin-right: 15px;
|
||||
font-size: 28px;
|
||||
}
|
||||
.facebook-button {
|
||||
background-color: #3b5998;
|
||||
padding-left: 5px;
|
||||
}
|
||||
.github-button {
|
||||
background-color: #333333;
|
||||
margin-right: 12px;
|
||||
padding-left: 5px;
|
||||
}
|
||||
.google-button {
|
||||
background-color: #4285F4;
|
||||
padding-left: 1px;
|
||||
img {
|
||||
margin-right: 10px;
|
||||
width: 14%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
button {
|
||||
@include login-button;
|
||||
}
|
||||
|
||||
form {
|
||||
background-color: $mycroft-white;
|
||||
border-radius: 10px;
|
||||
padding: 20px;
|
||||
fa-icon {
|
||||
color: $mycroft-dark-grey;
|
||||
margin-right: 15px;
|
||||
}
|
||||
mat-checkbox {
|
||||
color: $mycroft-dark-grey;
|
||||
}
|
||||
.forgot-password {
|
||||
margin-left: 30px;
|
||||
}
|
||||
button {
|
||||
background-color: $mycroft-primary;
|
||||
margin-top: 30px;
|
||||
text-align: center;
|
||||
}
|
||||
button:hover {
|
||||
background-color: $mycroft-tertiary-green;
|
||||
color: $mycroft-secondary;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.mat-body-2 {
|
||||
color: $mycroft-tertiary-red;
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
.mat-subheading-2 {
|
||||
color: $mycroft-dark-grey;
|
||||
margin-bottom: -15px;
|
||||
margin-top: -15px;
|
||||
text-align: center;
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { AuthComponent } from './auth.component';
|
||||
|
||||
describe('AuthComponent', () => {
|
||||
let component: AuthComponent;
|
||||
let fixture: ComponentFixture<AuthComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ AuthComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(AuthComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
|
@ -1,55 +0,0 @@
|
|||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
import { faFacebook, faGithub } from "@fortawesome/free-brands-svg-icons";
|
||||
import { faLock, faUser } from "@fortawesome/free-solid-svg-icons";
|
||||
|
||||
import { AuthResponse, AuthService } from "./auth.service";
|
||||
|
||||
@Component({
|
||||
selector: 'login-authenticate',
|
||||
templateUrl: './auth.component.html',
|
||||
styleUrls: ['./auth.component.scss']
|
||||
})
|
||||
export class AuthComponent implements OnInit {
|
||||
public facebookIcon = faFacebook;
|
||||
public githubIcon = faGithub;
|
||||
public authFailed: boolean;
|
||||
public password: string;
|
||||
public passwordIcon = faLock;
|
||||
public username: string;
|
||||
public usernameIcon = faUser;
|
||||
|
||||
constructor(private authService: AuthService) { }
|
||||
|
||||
ngOnInit() { }
|
||||
|
||||
authenticateFacebook(): void {
|
||||
this.authService.authenticateWithFacebook()
|
||||
}
|
||||
|
||||
authenticateGithub(): void {
|
||||
this.authService.authenticateWithGithub();
|
||||
}
|
||||
|
||||
authenticateGoogle(): void {
|
||||
this.authService.authenticateWithGoogle();
|
||||
}
|
||||
authorizeUser(): void {
|
||||
this.authService.authorizeAntisocial(this.username, this.password).subscribe(
|
||||
(response) => {this.onAuthSuccess(response)},
|
||||
(response) => {this.onAuthFailure(response)}
|
||||
);
|
||||
}
|
||||
|
||||
onAuthSuccess(authResponse: AuthResponse) {
|
||||
this.authFailed = false;
|
||||
this.authService.generateTokenCookies(authResponse);
|
||||
window.history.back();
|
||||
}
|
||||
|
||||
onAuthFailure(authorizeUserResponse) {
|
||||
if (authorizeUserResponse.status === 401) {
|
||||
this.authFailed = true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
import { AuthModule } from './auth.module';
|
||||
|
||||
describe('AuthModule', () => {
|
||||
let authenticateModule: AuthModule;
|
||||
|
||||
beforeEach(() => {
|
||||
authenticateModule = new AuthModule();
|
||||
});
|
||||
|
||||
it('should create an instance', () => {
|
||||
expect(authenticateModule).toBeTruthy();
|
||||
});
|
||||
});
|
|
@ -1,15 +0,0 @@
|
|||
import { TestBed, inject } from '@angular/core/testing';
|
||||
|
||||
import { AuthService } from './auth.service';
|
||||
|
||||
describe('AuthenticateService', () => {
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
providers: [AuthService]
|
||||
});
|
||||
});
|
||||
|
||||
it('should be created', inject([AuthService], (service: AuthService) => {
|
||||
expect(service).toBeTruthy();
|
||||
}));
|
||||
});
|
|
@ -0,0 +1,7 @@
|
|||
<div class="split top"></div>
|
||||
<div class="split bottom"></div>
|
||||
<div fxLayout="column" fxLayoutAlign="center center">
|
||||
<div align="center">
|
||||
<img src="../../assets/mycroft-ai-no-logo.svg"/>
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,30 @@
|
|||
@import "../../stylesheets/global";
|
||||
|
||||
/* Split the screen in half */
|
||||
.split {
|
||||
height: 50%;
|
||||
left: 0;
|
||||
overflow-x: hidden;
|
||||
padding-top: 20px;
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
/* Top Half */
|
||||
.top {
|
||||
top: 0;
|
||||
background-color: $mycroft-primary;
|
||||
}
|
||||
|
||||
/* Bottom Half */
|
||||
.bottom {
|
||||
bottom: 0;
|
||||
background-color: #e5e5e5;
|
||||
}
|
||||
|
||||
img {
|
||||
margin-bottom: 50px;
|
||||
margin-top: 50px;
|
||||
width: 600px;
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'login-background',
|
||||
templateUrl: './background.component.html',
|
||||
styleUrls: ['./background.component.scss']
|
||||
})
|
||||
export class BackgroundComponent implements OnInit {
|
||||
|
||||
constructor() { }
|
||||
|
||||
ngOnInit() { }
|
||||
|
||||
}
|
|
@ -1,18 +1,3 @@
|
|||
<div class="social">
|
||||
<button mat-button class="google-button" (click)="authenticateGoogle()">
|
||||
<img src="../../../assets/google-logo.svg">
|
||||
Log in with Google
|
||||
</button>
|
||||
<button mat-button class="facebook-button" (click)="authenticateFacebook()">
|
||||
<fa-icon [icon]="facebookIcon"></fa-icon>
|
||||
Continue with Facebook
|
||||
</button>
|
||||
<button mat-button class="github-button" (click)="authenticateGithub()">
|
||||
<fa-icon [icon]="githubIcon"></fa-icon>
|
||||
Log in with GitHub
|
||||
</button>
|
||||
</div>
|
||||
<div class="mat-subheading-2">OR</div>
|
||||
<form
|
||||
fxLayout="column"
|
||||
#loginForm="ngForm"
|
|
@ -0,0 +1,36 @@
|
|||
@import '../../../stylesheets/global';
|
||||
|
||||
button {
|
||||
@include login-button;
|
||||
}
|
||||
|
||||
form {
|
||||
background-color: $mycroft-white;
|
||||
border-radius: 10px;
|
||||
padding: 20px;
|
||||
fa-icon {
|
||||
color: $mycroft-dark-grey;
|
||||
margin-right: 15px;
|
||||
}
|
||||
mat-checkbox {
|
||||
color: $mycroft-dark-grey;
|
||||
}
|
||||
.forgot-password {
|
||||
margin-left: 30px;
|
||||
}
|
||||
button {
|
||||
background-color: $mycroft-primary;
|
||||
margin-top: 30px;
|
||||
text-align: center;
|
||||
}
|
||||
button:hover {
|
||||
background-color: $mycroft-tertiary-green;
|
||||
color: $mycroft-secondary;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.mat-body-2 {
|
||||
color: $mycroft-tertiary-red;
|
||||
padding: 15px;
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
import { faLock, faUser } from "@fortawesome/free-solid-svg-icons";
|
||||
|
||||
import { AuthResponse, LoginService } from "../login.service";
|
||||
|
||||
@Component({
|
||||
selector: 'login-antisocial',
|
||||
templateUrl: './antisocial.component.html',
|
||||
styleUrls: ['./antisocial.component.scss']
|
||||
})
|
||||
export class AntisocialComponent implements OnInit {
|
||||
public authFailed: boolean;
|
||||
public password: string;
|
||||
public passwordIcon = faLock;
|
||||
private redirectUri: string;
|
||||
public username: string;
|
||||
public usernameIcon = faUser;
|
||||
|
||||
constructor(private authService: LoginService) { }
|
||||
|
||||
ngOnInit() {
|
||||
this.redirectUri = decodeURIComponent(window.location.search).slice(10);
|
||||
}
|
||||
|
||||
authorizeUser(): void {
|
||||
this.authService.authorizeAntisocial(this.username, this.password).subscribe(
|
||||
(response) => {this.onAuthSuccess(response)},
|
||||
(response) => {this.onAuthFailure(response)}
|
||||
);
|
||||
}
|
||||
|
||||
onAuthSuccess(authResponse: AuthResponse): void {
|
||||
this.authFailed = false;
|
||||
this.authService.generateTokenCookies(authResponse);
|
||||
window.location.assign(this.redirectUri);
|
||||
}
|
||||
|
||||
onAuthFailure(authorizeUserResponse): void {
|
||||
if (authorizeUserResponse.status === 401) {
|
||||
this.authFailed = true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
<login-background></login-background>
|
||||
<div fxLayout="column" fxLayoutAlign="center center">
|
||||
<div class="login-options">
|
||||
<login-social></login-social>
|
||||
<div class="mat-subheading-2">OR</div>
|
||||
<login-antisocial></login-antisocial>
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,15 @@
|
|||
@import '../../stylesheets/global';
|
||||
|
||||
.login-options {
|
||||
background-color: $mycroft-white;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 1px 5px 0 rgba(0, 0, 0, 0.12);
|
||||
width: 320px;
|
||||
}
|
||||
|
||||
.mat-subheading-2 {
|
||||
color: $mycroft-dark-grey;
|
||||
margin-bottom: -15px;
|
||||
margin-top: -15px;
|
||||
text-align: center;
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'login-authenticate',
|
||||
templateUrl: './login.component.html',
|
||||
styleUrls: ['./login.component.scss']
|
||||
})
|
||||
export class LoginComponent implements OnInit {
|
||||
private redirectUri: string;
|
||||
|
||||
constructor() { }
|
||||
|
||||
ngOnInit() {
|
||||
this.redirectUri = decodeURIComponent(window.location.search).slice(10);
|
||||
}
|
||||
}
|
|
@ -14,12 +14,21 @@ import {
|
|||
|
||||
import { FontAwesomeModule } from "@fortawesome/angular-fontawesome";
|
||||
|
||||
import { AuthComponent } from './auth.component';
|
||||
import { AuthService } from "./auth.service";
|
||||
import { AntisocialComponent } from './antisocial/antisocial.component';
|
||||
import { LoginComponent } from './login.component';
|
||||
import { LoginService } from "./login.service";
|
||||
import { BackgroundComponent } from '../background/background.component';
|
||||
import { SocialComponent } from './social/social.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [ AuthComponent ],
|
||||
exports: [ AuthComponent ],
|
||||
declarations: [
|
||||
AntisocialComponent,
|
||||
LoginComponent,
|
||||
BackgroundComponent,
|
||||
SocialComponent
|
||||
],
|
||||
entryComponents: [ LoginComponent ],
|
||||
exports: [ LoginComponent ],
|
||||
imports: [
|
||||
CommonModule,
|
||||
FlexLayoutModule,
|
||||
|
@ -33,6 +42,6 @@ import { AuthService } from "./auth.service";
|
|||
MatInputModule,
|
||||
MatSnackBarModule
|
||||
],
|
||||
providers: [ AuthService ]
|
||||
providers: [ LoginService ]
|
||||
})
|
||||
export class AuthModule { }
|
||||
export class LoginModule { }
|
|
@ -20,7 +20,7 @@ export interface SocialLoginData {
|
|||
}
|
||||
|
||||
@Injectable()
|
||||
export class AuthService {
|
||||
export class LoginService {
|
||||
private antisocialAuthUrl = '/api/antisocial';
|
||||
private facebookAuthUrl = '/api/social/facebook';
|
||||
private githubAuthUrl = '/api/social/github';
|
|
@ -0,0 +1,14 @@
|
|||
<div class="social" fxLayout="column" fxLayoutAlign="center center">
|
||||
<button mat-button class="google-button" (click)="authenticateGoogle()">
|
||||
<img src="../../../assets/google-logo.svg">
|
||||
Log in with Google
|
||||
</button>
|
||||
<button mat-button class="facebook-button" (click)="authenticateFacebook()">
|
||||
<fa-icon [icon]="facebookIcon"></fa-icon>
|
||||
Continue with Facebook
|
||||
</button>
|
||||
<button mat-button class="github-button" (click)="authenticateGithub()">
|
||||
<fa-icon [icon]="githubIcon"></fa-icon>
|
||||
Log in with GitHub
|
||||
</button>
|
||||
</div>
|
|
@ -0,0 +1,33 @@
|
|||
@import '../../../stylesheets/global';
|
||||
|
||||
button {
|
||||
@include login-button;
|
||||
}
|
||||
|
||||
.social {
|
||||
padding: 20px;
|
||||
button {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
fa-icon {
|
||||
margin-right: 15px;
|
||||
font-size: 28px;
|
||||
}
|
||||
.facebook-button {
|
||||
background-color: #3b5998;
|
||||
padding-left: 5px;
|
||||
}
|
||||
.github-button {
|
||||
background-color: #333333;
|
||||
padding-left: 5px;
|
||||
}
|
||||
.google-button {
|
||||
background-color: #4285F4;
|
||||
padding-left: 1px;
|
||||
img {
|
||||
margin-right: 10px;
|
||||
width: 14%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
import { faFacebook, faGithub } from "@fortawesome/free-brands-svg-icons";
|
||||
|
||||
import { LoginService } from "../login.service";
|
||||
|
||||
@Component({
|
||||
selector: 'login-social',
|
||||
templateUrl: './social.component.html',
|
||||
styleUrls: ['./social.component.scss']
|
||||
})
|
||||
export class SocialComponent implements OnInit {
|
||||
public facebookIcon = faFacebook;
|
||||
public githubIcon = faGithub;
|
||||
|
||||
constructor(private authService: LoginService) { }
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
authenticateFacebook(): void {
|
||||
this.authService.authenticateWithFacebook()
|
||||
}
|
||||
|
||||
authenticateGithub(): void {
|
||||
this.authService.authenticateWithGithub();
|
||||
}
|
||||
|
||||
authenticateGoogle(): void {
|
||||
this.authService.authenticateWithGoogle();
|
||||
}
|
||||
|
||||
|
||||
}
|
Loading…
Reference in New Issue