diff --git a/login/backend/v1/login-api/login_api/endpoints/logout.py b/login/backend/v1/login-api/login_api/endpoints/logout.py
index 52407c3a..2f6f9921 100644
--- a/login/backend/v1/login-api/login_api/endpoints/logout.py
+++ b/login/backend/v1/login-api/login_api/endpoints/logout.py
@@ -14,7 +14,7 @@ class LogoutEndpoint(SeleneEndpoint):
def __init__(self):
super(LogoutEndpoint, self).__init__()
- def put(self):
+ def get(self):
try:
self._authenticate()
self._logout()
@@ -33,5 +33,5 @@ def _logout(self):
headers=service_request_headers
)
self._check_for_service_errors(auth_service_response)
- logout_response = auth_service_response.json()
+ logout_response = auth_service_response.content.decode()
self.response = (logout_response, HTTPStatus.OK)
diff --git a/login/frontend/v1/login-ui/src/app/app-routing.module.ts b/login/frontend/v1/login-ui/src/app/app-routing.module.ts
new file mode 100644
index 00000000..5f127289
--- /dev/null
+++ b/login/frontend/v1/login-ui/src/app/app-routing.module.ts
@@ -0,0 +1,19 @@
+import { NgModule } from '@angular/core';
+import { Routes, RouterModule } from '@angular/router';
+
+import { LoginComponent } from "./login/login.component";
+import { LogoutComponent } from "./logout/logout.component";
+// import { PageNotFoundComponent } from "./page-not-found/page-not-found.component";
+
+const routes: Routes = [
+ { path: 'login', component: LoginComponent },
+ { path: 'logout', component: LogoutComponent },
+ // { path: '**', component: PageNotFoundComponent }
+];
+
+@NgModule({
+ imports: [ RouterModule.forRoot(routes) ],
+ exports: [ RouterModule ]
+})
+export class AppRoutingModule {
+}
diff --git a/login/frontend/v1/login-ui/src/app/app.component.html b/login/frontend/v1/login-ui/src/app/app.component.html
index 642d4ed7..78635d9c 100644
--- a/login/frontend/v1/login-ui/src/app/app.component.html
+++ b/login/frontend/v1/login-ui/src/app/app.component.html
@@ -8,24 +8,6 @@
is refactored and moved into Selene.
-->
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
diff --git a/login/frontend/v1/login-ui/src/app/app.component.spec.ts b/login/frontend/v1/login-ui/src/app/app.component.spec.ts
deleted file mode 100644
index decc5585..00000000
--- a/login/frontend/v1/login-ui/src/app/app.component.spec.ts
+++ /dev/null
@@ -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!');
- }));
-});
diff --git a/login/frontend/v1/login-ui/src/app/app.component.ts b/login/frontend/v1/login-ui/src/app/app.component.ts
index 63cf067d..1aeee9af 100644
--- a/login/frontend/v1/login-ui/src/app/app.component.ts
+++ b/login/frontend/v1/login-ui/src/app/app.component.ts
@@ -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();
diff --git a/login/frontend/v1/login-ui/src/app/app.module.ts b/login/frontend/v1/login-ui/src/app/app.module.ts
index f9ba7c1a..52241c4a 100644
--- a/login/frontend/v1/login-ui/src/app/app.module.ts
+++ b/login/frontend/v1/login-ui/src/app/app.module.ts
@@ -4,15 +4,21 @@ 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 { BackgroundModule } from "./background/background.module";
+import { LoginModule } from "./login/login.module";
+import { LogoutModule } from "./logout/logout.module";
@NgModule({
declarations: [ AppComponent ],
imports: [
BrowserModule,
- AuthModule,
+ BackgroundModule,
BrowserAnimationsModule,
- FlexLayoutModule
+ FlexLayoutModule,
+ LoginModule,
+ LogoutModule,
+ AppRoutingModule
],
providers: [ ],
bootstrap: [ AppComponent ]
diff --git a/login/frontend/v1/login-ui/src/app/app.service.ts b/login/frontend/v1/login-ui/src/app/app.service.ts
new file mode 100644
index 00000000..c28bd943
--- /dev/null
+++ b/login/frontend/v1/login-ui/src/app/app.service.ts
@@ -0,0 +1,91 @@
+import { Injectable } from '@angular/core';
+import { HttpClient, HttpHeaders} from "@angular/common/http";
+
+import { Observable } from 'rxjs';
+
+export interface AuthResponse {
+ expiration: number;
+ seleneToken: string;
+ tartarusToken: string;
+}
+
+export interface SocialLoginData {
+ uuid: string;
+ accessToken: string;
+ refreshToken: string;
+ expiration: string;
+}
+
+const antisocialAuthUrl = '/api/antisocial';
+const facebookAuthUrl = '/api/social/facebook';
+const githubAuthUrl = '/api/social/github';
+const googleAuthUrl = '/api/social/google';
+const generateTokensUrl = 'api/social/tokens';
+const logoutUrl = '/api/logout';
+
+
+@Injectable()
+export class AppService {
+ private cookieDomain: string = document.domain.replace('login.', '');
+
+ constructor(private http: HttpClient) { }
+
+ navigateToRedirectURI(delay: number): void {
+ let redirectURI = localStorage.getItem('redirect');
+ localStorage.removeItem('redirect');
+ setTimeout(() => { window.location.assign(redirectURI) }, delay);
+ }
+
+ authorizeAntisocial (username, password): Observable {
+ let rawCredentials = `${username}:${password}`;
+ const codedCredentials = btoa(rawCredentials);
+ const httpHeaders = new HttpHeaders(
+ {"Authorization": "Basic " + codedCredentials}
+ );
+ return this.http.get(antisocialAuthUrl, {headers: httpHeaders})
+ }
+
+ authenticateWithFacebook() {
+ window.location.assign(facebookAuthUrl);
+ }
+
+ authenticateWithGithub() {
+ window.location.assign(githubAuthUrl);
+ }
+
+ authenticateWithGoogle() {
+ window.location.assign(googleAuthUrl);
+ }
+
+ generateSocialLoginTokens(socialLoginData: any) {
+ return this.http.post(
+ generateTokensUrl,
+ socialLoginData
+ );
+ }
+
+ generateTokenCookies(authResponse: AuthResponse) {
+ let expirationDate = new Date(authResponse.expiration * 1000);
+ document.cookie = 'seleneToken=' + authResponse.seleneToken +
+ '; expires=' + expirationDate.toUTCString() +
+ '; domain=' + this.cookieDomain;
+ document.cookie = 'tartarusToken=' + authResponse.tartarusToken +
+ '; expires=' + expirationDate.toUTCString() +
+ '; domain=' + this.cookieDomain;
+ }
+
+ logout(): Observable {
+ return this.http.get(logoutUrl);
+ }
+
+ expireTokenCookies(): void {
+ let expiration = new Date();
+ document.cookie = 'seleneToken=""' +
+ '; expires=' + expiration.toUTCString() +
+ '; domain=' + this.cookieDomain;
+ document.cookie = 'tartarusToken=""' +
+ '; expires=' + expiration.toUTCString() +
+ '; domain=' + this.cookieDomain;
+
+ }
+}
diff --git a/login/frontend/v1/login-ui/src/app/auth/auth.component.scss b/login/frontend/v1/login-ui/src/app/auth/auth.component.scss
deleted file mode 100644
index 8cb3e4a7..00000000
--- a/login/frontend/v1/login-ui/src/app/auth/auth.component.scss
+++ /dev/null
@@ -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;
-}
diff --git a/login/frontend/v1/login-ui/src/app/auth/auth.component.spec.ts b/login/frontend/v1/login-ui/src/app/auth/auth.component.spec.ts
deleted file mode 100644
index 884576c8..00000000
--- a/login/frontend/v1/login-ui/src/app/auth/auth.component.spec.ts
+++ /dev/null
@@ -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;
-
- beforeEach(async(() => {
- TestBed.configureTestingModule({
- declarations: [ AuthComponent ]
- })
- .compileComponents();
- }));
-
- beforeEach(() => {
- fixture = TestBed.createComponent(AuthComponent);
- component = fixture.componentInstance;
- fixture.detectChanges();
- });
-
- it('should create', () => {
- expect(component).toBeTruthy();
- });
-});
diff --git a/login/frontend/v1/login-ui/src/app/auth/auth.component.ts b/login/frontend/v1/login-ui/src/app/auth/auth.component.ts
deleted file mode 100644
index 3912a95b..00000000
--- a/login/frontend/v1/login-ui/src/app/auth/auth.component.ts
+++ /dev/null
@@ -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;
- }
- }
-}
diff --git a/login/frontend/v1/login-ui/src/app/auth/auth.module.spec.ts b/login/frontend/v1/login-ui/src/app/auth/auth.module.spec.ts
deleted file mode 100644
index 561ea04a..00000000
--- a/login/frontend/v1/login-ui/src/app/auth/auth.module.spec.ts
+++ /dev/null
@@ -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();
- });
-});
diff --git a/login/frontend/v1/login-ui/src/app/auth/auth.service.spec.ts b/login/frontend/v1/login-ui/src/app/auth/auth.service.spec.ts
deleted file mode 100644
index f4cc85af..00000000
--- a/login/frontend/v1/login-ui/src/app/auth/auth.service.spec.ts
+++ /dev/null
@@ -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();
- }));
-});
diff --git a/login/frontend/v1/login-ui/src/app/auth/auth.service.ts b/login/frontend/v1/login-ui/src/app/auth/auth.service.ts
deleted file mode 100644
index 3176c70d..00000000
--- a/login/frontend/v1/login-ui/src/app/auth/auth.service.ts
+++ /dev/null
@@ -1,109 +0,0 @@
-import { Injectable } from '@angular/core';
-import { HttpClient, HttpHeaders} from "@angular/common/http";
-
-import { Observable } from 'rxjs';
-import { isArray } from "util";
-
-import { MatSnackBar } from "@angular/material";
-
-export interface AuthResponse {
- expiration: number;
- seleneToken: string;
- tartarusToken: string;
-}
-
-export interface SocialLoginData {
- uuid: string;
- accessToken: string;
- refreshToken: string;
- expiration: string;
-}
-
-@Injectable()
-export class AuthService {
- private antisocialAuthUrl = '/api/antisocial';
- private facebookAuthUrl = '/api/social/facebook';
- private githubAuthUrl = '/api/social/github';
- private googleAuthUrl = '/api/social/google';
- private generateTokensUrl = 'api/social/tokens';
-
- constructor(private http: HttpClient, public loginSnackbar: MatSnackBar) {
- }
-
- authorizeAntisocial (username, password): Observable {
- let rawCredentials = `${username}:${password}`;
- const codedCredentials = btoa(rawCredentials);
- const httpHeaders = new HttpHeaders(
- {"Authorization": "Basic " + codedCredentials}
- );
- return this.http.get(this.antisocialAuthUrl, {headers: httpHeaders})
- }
-
- authenticateWithFacebook() {
- window.open(this.facebookAuthUrl);
- window.onmessage = (event) => {this.generateSocialLoginTokens(event)};
- }
-
- authenticateWithGithub() {
- window.open(this.githubAuthUrl);
- window.onmessage = (event) => {this.generateSocialLoginTokens(event)};
- }
-
- authenticateWithGoogle() {
- window.open(this.googleAuthUrl);
- window.onmessage = (event) => {this.generateSocialLoginTokens(event)};
- }
-
- generateSocialLoginTokens(event: any) {
- let socialLoginData = this.parseUriParams(event.data);
- if (socialLoginData) {
- this.http.post(
- this.generateTokensUrl,
- socialLoginData
- ).subscribe(
- (response) => {this.generateTokenCookies(response)}
- );
- }
- return this.http.post(
- this.generateTokensUrl,
- socialLoginData
- )
- }
-
- parseUriParams (uriParams: string) {
- let socialLoginData: SocialLoginData = null;
-
- if (uriParams.startsWith('?data=')) {
- let parsedUriParams = JSON.parse(uriParams.slice(6));
- if (isArray(parsedUriParams)) {
- let socialLoginErrorMsg = 'An account exists for the email ' +
- 'address associated with the social network log in ' +
- 'attempt. To enable log in using a social network, log ' +
- 'in with your username and password and enable the ' +
- 'social network in your account preferences.';
- this.loginSnackbar.open(
- socialLoginErrorMsg,
- null,
- {duration: 30000}
- );
- } else {
- socialLoginData = parsedUriParams;
- }
- }
-
- return socialLoginData
- }
-
- generateTokenCookies(authResponse: AuthResponse) {
- let expirationDate = new Date(authResponse.expiration * 1000);
- let domain = document.domain.replace('login.', '');
- document.cookie = 'seleneToken=' + authResponse.seleneToken +
- '; expires=' + expirationDate.toUTCString() +
- '; domain=' + domain;
- document.cookie = 'tartarusToken=' + authResponse.tartarusToken +
- '; expires=' + expirationDate.toUTCString() +
- '; domain=' + domain;
- }
-
-
-}
diff --git a/login/frontend/v1/login-ui/src/app/background/background.component.html b/login/frontend/v1/login-ui/src/app/background/background.component.html
new file mode 100644
index 00000000..304e0ba9
--- /dev/null
+++ b/login/frontend/v1/login-ui/src/app/background/background.component.html
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/login/frontend/v1/login-ui/src/app/background/background.component.scss b/login/frontend/v1/login-ui/src/app/background/background.component.scss
new file mode 100644
index 00000000..572dc6fc
--- /dev/null
+++ b/login/frontend/v1/login-ui/src/app/background/background.component.scss
@@ -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;
+}
diff --git a/login/frontend/v1/login-ui/src/app/background/background.component.ts b/login/frontend/v1/login-ui/src/app/background/background.component.ts
new file mode 100644
index 00000000..04942f32
--- /dev/null
+++ b/login/frontend/v1/login-ui/src/app/background/background.component.ts
@@ -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() { }
+
+}
diff --git a/login/frontend/v1/login-ui/src/app/background/background.module.ts b/login/frontend/v1/login-ui/src/app/background/background.module.ts
new file mode 100644
index 00000000..a1bce3c9
--- /dev/null
+++ b/login/frontend/v1/login-ui/src/app/background/background.module.ts
@@ -0,0 +1,10 @@
+import { NgModule } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import { BackgroundComponent } from "./background.component";
+
+@NgModule({
+ declarations: [ BackgroundComponent ],
+ exports: [ BackgroundComponent ],
+ imports: [ CommonModule ],
+})
+export class BackgroundModule { }
diff --git a/login/frontend/v1/login-ui/src/app/auth/auth.component.html b/login/frontend/v1/login-ui/src/app/login/antisocial/antisocial.component.html
similarity index 63%
rename from login/frontend/v1/login-ui/src/app/auth/auth.component.html
rename to login/frontend/v1/login-ui/src/app/login/antisocial/antisocial.component.html
index 13a4199b..57cdd6e6 100644
--- a/login/frontend/v1/login-ui/src/app/auth/auth.component.html
+++ b/login/frontend/v1/login-ui/src/app/login/antisocial/antisocial.component.html
@@ -1,18 +1,3 @@
-
-
-
-
-
-OR