Skip to content

Commit

Permalink
Login is taking shape
Browse files Browse the repository at this point in the history
  • Loading branch information
duncte123 committed Nov 12, 2023
1 parent add681a commit fc4e31a
Show file tree
Hide file tree
Showing 12 changed files with 212 additions and 51 deletions.
36 changes: 36 additions & 0 deletions languagePropertyCopier.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Simple script that helps me copy translations and save our translators some time if I'm just copying.

const fs = require('fs');
const path = require('path');

const rootDir = path.resolve(__dirname, 'src', 'assets', 'i18n');
const jsonFiles = fs.readdirSync(rootDir).filter((file) => file.endsWith('.json'));

for (const file of jsonFiles) {
const filePath = path.resolve(rootDir, file);
const json = fs.readFileSync(filePath, 'utf8');
const obj = JSON.parse(json);

if (obj.navbar?.login?.discord) {
obj.login = { ...obj.login };
obj.login.provider = {...obj.login.provider };

obj.login.provider.discord = obj.navbar.login.discord;
}

if (obj.navbar?.login?.twitch) {
obj.login = { ...obj.login };
obj.login.provider = {...obj.login.provider };

obj.login.provider.twitch = obj.navbar.login.twitch;
}

if (obj.navbar?.login?.google) {
obj.login = { ...obj.login };
obj.login.provider = {...obj.login.provider };

obj.login.provider.google = obj.navbar.login.google;
}

fs.writeFileSync(filePath, JSON.stringify(obj, null, 2));
}
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,12 @@
<app-header-language-picker class="navbar-item pr-0"></app-header-language-picker>
<app-header-bar-user *ngIf="userService.user; else loggedOut" class="navbar-item pl-0"></app-header-bar-user>
<ng-template #loggedOut>
<app-widget-signin-picker type="NAVBAR" class="pl-0" [isRight]="true"></app-widget-signin-picker>
<a [routerLink]="'/login' | localize" class="navbar-item">
{{ 'navbar.login.title' | translate }}
</a>
<a [routerLink]="'/register' | localize" class="navbar-item">
{{ 'navbar.register' | translate }}
</a>
</ng-template>
</div>
</div>
Expand Down
95 changes: 59 additions & 36 deletions src/app/auth/login/login.component.html
Original file line number Diff line number Diff line change
@@ -1,67 +1,90 @@
<section class="section container">
<h1 class="title">Log-in to your Oengus account</h1>
<h1 class="title">{{ 'login.title' | translate }}</h1>

<div class="notification" *ngIf="loginError == 'USERNAME_PASSWORD_INCORRECT'">
<button class="delete" (click)="loginError = null"></button>
Lorem ipsum dolor sit amet, consectetur
adipiscing elit lorem ipsum dolor. <strong>Pellentesque risus mi</strong>, tempus quis placerat ut, porta nec nulla. Vestibulum rhoncus ac ex sit amet fringilla. Nullam gravida purus diam, et dictum <a>felis venenatis</a> efficitur.
</div>

<div class="columns">
<div class="column is-three-fifths is-offset-one-fifth">
<form action="">

<div class="field">
<label class="label">Username</label>
<div class="control has-icons-left">
<input class="input" type="text" placeholder="OengusIO" name="username" [disabled]="loading" [(ngModel)]="loginData.username">
<span class="icon is-small is-left">
<fieldset [disabled]="loading">
<div class="field">
<label class="label">{{ 'user.settings.username.label' | translate }}</label>
<div class="control has-icons-left">
<input class="input" type="text" placeholder="OengusIO" name="username" [(ngModel)]="loginData.username">
<span class="icon is-small is-left">
<fa-icon [icon]="iconUser"></fa-icon>
</span>
</div>
</div>
</div>


<label class="label">Password</label>
<div class="field has-addons">
<div class="control has-icons-left is-expanded">
<input class="input" type="password" name="password" placeholder="********" [disabled]="loading" *ngIf="passwordHidden; else plainTextPw" [(ngModel)]="loginData.password">
<ng-template #plainTextPw>
<input class="input" type="text" name="password" placeholder="password" [disabled]="loading" [(ngModel)]="loginData.password">
</ng-template>
<span class="icon is-small is-left">
<label class="label">{{ 'user.settings.password.label' | translate }}</label>
<div class="field has-addons">
<div class="control has-icons-left is-expanded">
<input class="input" type="password" name="password" placeholder="********" *ngIf="passwordHidden; else plainTextPw" [(ngModel)]="loginData.password">
<ng-template #plainTextPw>
<input class="input" type="text" name="password" placeholder="password" [(ngModel)]="loginData.password">
</ng-template>
<span class="icon is-small is-left">
<fa-icon [icon]="iconPadlock"></fa-icon>
</span>
</div>
</div>

<div class="control">
<button class="button" [disabled]="loading" (click)="passwordHidden = !passwordHidden">
<div class="control">
<button class="button" (click)="passwordHidden = !passwordHidden">
<span class="icon cursor-pointer">
<fa-icon [icon]="iconEye" *ngIf="passwordHidden; else eyeSlash"></fa-icon>
<fa-icon [title]="'login.password.show' | translate" [icon]="iconEye" *ngIf="passwordHidden; else eyeSlash"></fa-icon>
<ng-template #eyeSlash>
<fa-icon [icon]="iconEyeSlash"></fa-icon>
</ng-template>
</span>
</button>
</button>
</div>
</div>

<div class="field" *ngIf="mfaNeeded">
<label class="label">{{ 'login.2fa.label' | translate }}</label>
<div class="control">
<input class="input" type="text" placeholder="000000" name="2fa" [(ngModel)]="loginData.twoFactorCode" />
</div>
</div>
</div>

<div class="control">
<button type="submit" style="margin-right: 1rem"
[ngClass]="{'is-loading': loading}"
(click)="performLogin()"
class="button is-primary">{{'action.login' | translate}}</button>
</div>
<div class="control">
<button type="submit" style="margin-right: 1rem"
[ngClass]="{'is-loading': loading}"
(click)="performLogin()"
class="button is-primary">{{'login.button' | translate}}</button>
</div>
</fieldset>

</form>
</div>
</div>

<hr/>
<h2 class="subtitle">
Log-in with a provider
{{ 'login.provider.title' | translate }}
</h2>

<div class="columns">
<div class="column is-one-fifth is-offset-3">
<button class="button">Discord</button>
</div>
<div class="column is-one-fifth">
<button class="button">Twitch</button>
</div>
<div class="buttons is-centered are-large">
<a [href]="userService.getDiscordAuthUri()" class="button is-discord">
<span class="icon">
<fa-icon [icon]="iconDiscord"></fa-icon>
</span>
<span>{{ 'login.provider.discord' | translate }}</span>
</a>
<a [href]="userService.getTwitchAuthUrl()" class="button is-twitch">
<span class="icon">
<fa-icon [icon]="iconTwitch"></fa-icon>
</span>
<span>{{ 'login.provider.twitch' | translate }}</span>
</a>
<!--<button class="button is-static">
{{ 'login.provider.google' | translate }}
</button>-->
</div>
</section>
1 change: 1 addition & 0 deletions src/app/auth/login/login.component.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

49 changes: 39 additions & 10 deletions src/app/auth/login/login.component.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { Component, OnInit } from '@angular/core';
import { faUser, faLock, faEye, faEyeSlash } from '@fortawesome/free-solid-svg-icons';
import { faDiscord } from '@fortawesome/free-brands-svg-icons';
import { faEye, faEyeSlash, faLock, faUser } from '@fortawesome/free-solid-svg-icons';
import { faDiscord, faTwitch } from '@fortawesome/free-brands-svg-icons';
import { UserService } from '../../../services/user.service';
import { LoginDetails, LoginResponse, LoginResponseStatus } from '../../../model/auth';
import { AuthService } from '../../../services/auth.service';

@Component({
selector: 'app-login',
Expand All @@ -9,31 +12,57 @@ import { faDiscord } from '@fortawesome/free-brands-svg-icons';
})
export class LoginComponent implements OnInit {

loginData: {
username: string;
password: string;
mfaCode: string;
} = {
loginData: LoginDetails = {
username: '',
password: '',
mfaCode: ''
twoFactorCode: ''
};

loginError: LoginResponseStatus | null = LoginResponseStatus.USERNAME_PASSWORD_INCORRECT;
loading = false;
passwordHidden = true;
mfaNeeded: boolean = !!localStorage.getItem('alwaysShowMfa');

iconUser = faUser;
iconPadlock = faLock;
iconEye = faEye;
iconEyeSlash = faEyeSlash;
iconDiscord = faDiscord;
iconTwitch = faTwitch;


constructor() { }
constructor(
public userService: UserService,
private authService: AuthService,
) { }

ngOnInit(): void {
}

performLogin(): void {
this.loading = true;
this.passwordHidden = true;

this.authService.performLogin(this.loginData).subscribe({
next(response) {
console.log(response);

switch (response.status) {
case LoginResponseStatus.LOGIN_SUCCESS:
return;
case LoginResponseStatus.MFA_INVALID:
return;
case LoginResponseStatus.MFA_REQUIRED:
this.loading = false;
this.mfaNeeded = true;
return;
case LoginResponseStatus.USERNAME_PASSWORD_INCORRECT:
return;
}
},

error({ error }: { error: LoginResponse }) {
this.loginError = error.status;
}
});
}
}
2 changes: 1 addition & 1 deletion src/assets/i18n
Submodule i18n updated from 779b65 to 9831d9
5 changes: 5 additions & 0 deletions src/assets/themes/default.scss
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,14 @@ $title-color: color.scale($title-color, $lightness: $-lightness-change);
$subtitle-color: $title-color;
$code: #ffc8e2;

$discordBlurple: #5865F2;
$twitchPurple: #9146FF;
$googleWhite: #000000;

@import 'bulma';
@import 'bulmaswatch/solar/overrides';
@import '@duncte123/bulma-tagsinput/src/sass/index';
@import './elements';

@import 'bulma-extensions/dist/css/bulma-extensions.min.css';
@import 'bulma-extensions/bulma-tooltip/src/sass/index';
Expand Down
20 changes: 20 additions & 0 deletions src/assets/themes/elements.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
@use 'sass:color' as color;

.button.is-twitch {
color: white;
border-color: white;
background-color: $twitchPurple;

&:hover {
background-color: color.scale($twitchPurple, $saturation: -40%);
}
}
.button.is-discord {
color: white;
border-color: white;
background-color: $discordBlurple;

&:hover {
background-color: color.scale($discordBlurple, $saturation: -40%);
}
}
4 changes: 2 additions & 2 deletions src/environments/environment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ export const environment = {
// this is the base of the website where the users will land
baseSite: 'http://localhost:4200',
// the api that the front-end talks to
// api: 'http://localhost:8080',
api: 'https://oengus.dev/api',
api: 'http://localhost:8080',
// api: 'https://oengus.dev/api',
// api: 'https://oengus.io/api',
// Optional, in case of a custom hosted patreon api, will use api by default
// patronApi: 'http://localhost:9000',
Expand Down
17 changes: 17 additions & 0 deletions src/model/auth.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
export interface LoginDetails {
username: string;
password: string;
twoFactorCode: string | null;
}

export interface LoginResponse {
token: string | null;
status: LoginResponseStatus;
}

export enum LoginResponseStatus {
MFA_REQUIRED = 'MFA_REQUIRED',
MFA_INVALID = 'MFA_INVALID',
LOGIN_SUCCESS = 'LOGIN_SUCCESS',
USERNAME_PASSWORD_INCORRECT = 'USERNAME_PASSWORD_INCORRECT',
}
25 changes: 25 additions & 0 deletions src/services/auth.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { Injectable } from '@angular/core';
import { HttpClient, HttpParams } from '@angular/common/http';
import { NwbAlertService } from '@wizishop/ng-wizi-bulma';
import { Router } from '@angular/router';
import { Observable } from 'rxjs';
import { BaseService } from './BaseService';
import { LoginDetails, LoginResponse } from '../model/auth';

@Injectable({
providedIn: 'root'
})
export class AuthService extends BaseService {

constructor(private http: HttpClient,
private router: Router,
toastr: NwbAlertService) {
super(toastr, 'auth');
}

performLogin(details: LoginDetails): Observable<LoginResponse> {
details.twoFactorCode = details.twoFactorCode || null;

return this.http.post<LoginResponse>(this.url('login', 'v2'), details);
}
}
2 changes: 1 addition & 1 deletion src/services/user.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ export class UserService extends BaseService {
}

getProfile(name: string): Observable<UserProfile> {
return this.http.get<UserProfile>(this.url(`${name}`));
return this.http.get<UserProfile>(this.url(name));
}

isBanned(): boolean {
Expand Down

0 comments on commit fc4e31a

Please sign in to comment.