Add external login buttons
This commit is contained in:
parent
9107d791e2
commit
ebefc902f5
|
@ -23,40 +23,54 @@
|
||||||
<span *ngIf="error === 'User email is not verified.'"> <a i18n routerLink="/verify-account/ask-send-email">Request new verification email.</a></span>
|
<span *ngIf="error === 'User email is not verified.'"> <a i18n routerLink="/verify-account/ask-send-email">Request new verification email.</a></span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<form role="form" (ngSubmit)="login()" [formGroup]="form">
|
<div class="login-form-and-externals">
|
||||||
<div class="form-group">
|
|
||||||
<div>
|
<form role="form" (ngSubmit)="login()" [formGroup]="form">
|
||||||
<label i18n for="username">User</label>
|
<div class="form-group">
|
||||||
<input
|
<div>
|
||||||
type="text" id="username" i18n-placeholder placeholder="Username or email address" required tabindex="1"
|
<label i18n for="username">User</label>
|
||||||
formControlName="username" class="form-control" [ngClass]="{ 'input-error': formErrors['username'] }" #emailInput
|
<input
|
||||||
>
|
type="text" id="username" i18n-placeholder placeholder="Username or email address" required tabindex="1"
|
||||||
<a i18n *ngIf="signupAllowed === true" routerLink="/signup" class="create-an-account">
|
formControlName="username" class="form-control" [ngClass]="{ 'input-error': formErrors['username'] }" #usernameInput
|
||||||
or create an account
|
>
|
||||||
|
<a i18n *ngIf="signupAllowed === true" routerLink="/signup" class="create-an-account">
|
||||||
|
or create an account
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div *ngIf="formErrors.username" class="form-error">
|
||||||
|
{{ formErrors.username }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label i18n for="password">Password</label>
|
||||||
|
<div>
|
||||||
|
<input
|
||||||
|
type="password" name="password" id="password" i18n-placeholder placeholder="Password" required tabindex="2" autocomplete="current-password"
|
||||||
|
formControlName="password" class="form-control" [ngClass]="{ 'input-error': formErrors['password'] }"
|
||||||
|
>
|
||||||
|
<a i18n-title class="forgot-password-button" (click)="openForgotPasswordModal()" title="Click here to reset your password">I forgot my password</a>
|
||||||
|
</div>
|
||||||
|
<div *ngIf="formErrors.password" class="form-error">
|
||||||
|
{{ formErrors.password }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<input type="submit" i18n-value value="Login" [disabled]="!form.valid">
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<div class="external-login-blocks" *ngIf="getExternalLogins().length !== 0">
|
||||||
|
<div class="block-title" i18n>Or sign in with</div>
|
||||||
|
|
||||||
|
<div class="external-login-block">
|
||||||
|
<a *ngFor="let auth of getExternalLogins()" [href]="getAuthHref(auth)" role="button">
|
||||||
|
{{ auth.authDisplayName }}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div *ngIf="formErrors.username" class="form-error">
|
|
||||||
{{ formErrors.username }}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<label i18n for="password">Password</label>
|
|
||||||
<div>
|
|
||||||
<input
|
|
||||||
type="password" name="password" id="password" i18n-placeholder placeholder="Password" required tabindex="2" autocomplete="current-password"
|
|
||||||
formControlName="password" class="form-control" [ngClass]="{ 'input-error': formErrors['password'] }"
|
|
||||||
>
|
|
||||||
<a i18n-title class="forgot-password-button" (click)="openForgotPasswordModal()" title="Click here to reset your password">I forgot my password</a>
|
|
||||||
</div>
|
|
||||||
<div *ngIf="formErrors.password" class="form-error">
|
|
||||||
{{ formErrors.password }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<input type="submit" i18n-value value="Login" [disabled]="!form.valid">
|
|
||||||
</form>
|
|
||||||
</ng-container>
|
</ng-container>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -21,9 +21,49 @@ input[type=submit] {
|
||||||
color: var(--mainForegroundColor);
|
color: var(--mainForegroundColor);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: opacity cubic-bezier(0.39, 0.575, 0.565, 1);
|
transition: opacity cubic-bezier(0.39, 0.575, 0.565, 1);
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
text-decoration: none !important;
|
text-decoration: none !important;
|
||||||
opacity: .7 !important;
|
opacity: .7 !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.login-form-and-externals {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
font-size: 15px;
|
||||||
|
|
||||||
|
form {
|
||||||
|
margin: 0 50px 20px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.external-login-blocks {
|
||||||
|
padding: 0 10px 10px 10px;
|
||||||
|
min-width: 200px;
|
||||||
|
|
||||||
|
.block-title {
|
||||||
|
font-weight: $font-semibold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.external-login-block {
|
||||||
|
cursor: pointer;
|
||||||
|
border: 1px solid #d1d7e0;
|
||||||
|
border-radius: 5px;
|
||||||
|
margin: 10px 10px 0 0;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
min-height: 35px;
|
||||||
|
min-width: 100px;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: rgba(209, 215, 224, 0.5)
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
@include disable-default-a-behaviour;
|
||||||
|
color: var(--mainForegroundColor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { Component, ElementRef, OnInit, ViewChild } from '@angular/core'
|
import { Component, ElementRef, OnInit, ViewChild, AfterViewInit } from '@angular/core'
|
||||||
import { Notifier, RedirectService } from '@app/core'
|
import { Notifier, RedirectService } from '@app/core'
|
||||||
import { UserService } from '@app/shared'
|
import { UserService } from '@app/shared'
|
||||||
import { AuthService } from '../core'
|
import { AuthService } from '../core'
|
||||||
|
@ -8,7 +8,8 @@ import { FormValidatorService } from '@app/shared/forms/form-validators/form-val
|
||||||
import { LoginValidatorsService } from '@app/shared/forms/form-validators/login-validators.service'
|
import { LoginValidatorsService } from '@app/shared/forms/form-validators/login-validators.service'
|
||||||
import { NgbModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap'
|
import { NgbModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap'
|
||||||
import { ActivatedRoute } from '@angular/router'
|
import { ActivatedRoute } from '@angular/router'
|
||||||
import { ServerConfig } from '@shared/models/server/server-config.model'
|
import { ServerConfig, RegisteredExternalAuthConfig } from '@shared/models/server/server-config.model'
|
||||||
|
import { environment } from 'src/environments/environment'
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'my-login',
|
selector: 'my-login',
|
||||||
|
@ -16,13 +17,14 @@ import { ServerConfig } from '@shared/models/server/server-config.model'
|
||||||
styleUrls: [ './login.component.scss' ]
|
styleUrls: [ './login.component.scss' ]
|
||||||
})
|
})
|
||||||
|
|
||||||
export class LoginComponent extends FormReactive implements OnInit {
|
export class LoginComponent extends FormReactive implements OnInit, AfterViewInit {
|
||||||
@ViewChild('emailInput', { static: true }) input: ElementRef
|
@ViewChild('usernameInput', { static: false }) usernameInput: ElementRef
|
||||||
@ViewChild('forgotPasswordModal', { static: true }) forgotPasswordModal: ElementRef
|
@ViewChild('forgotPasswordModal', { static: true }) forgotPasswordModal: ElementRef
|
||||||
|
|
||||||
error: string = null
|
error: string = null
|
||||||
forgotPasswordEmail = ''
|
forgotPasswordEmail = ''
|
||||||
isAuthenticatedWithExternalAuth = false
|
isAuthenticatedWithExternalAuth = false
|
||||||
|
externalLogins: string[] = []
|
||||||
|
|
||||||
private openedForgotPasswordModal: NgbModalRef
|
private openedForgotPasswordModal: NgbModalRef
|
||||||
private serverConfig: ServerConfig
|
private serverConfig: ServerConfig
|
||||||
|
@ -63,8 +65,20 @@ export class LoginComponent extends FormReactive implements OnInit {
|
||||||
username: this.loginValidatorsService.LOGIN_USERNAME,
|
username: this.loginValidatorsService.LOGIN_USERNAME,
|
||||||
password: this.loginValidatorsService.LOGIN_PASSWORD
|
password: this.loginValidatorsService.LOGIN_PASSWORD
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
|
||||||
this.input.nativeElement.focus()
|
ngAfterViewInit () {
|
||||||
|
if (this.usernameInput) {
|
||||||
|
this.usernameInput.nativeElement.focus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getExternalLogins () {
|
||||||
|
return this.serverConfig.plugin.registeredExternalAuths
|
||||||
|
}
|
||||||
|
|
||||||
|
getAuthHref (auth: RegisteredExternalAuthConfig) {
|
||||||
|
return environment.apiUrl + `/plugins/${auth.name}/${auth.version}/auth/${auth.authName}`
|
||||||
}
|
}
|
||||||
|
|
||||||
login () {
|
login () {
|
||||||
|
|
|
@ -53,8 +53,6 @@ $sub-menu-color: #F7F7F7;
|
||||||
$footer-height: 30px;
|
$footer-height: 30px;
|
||||||
$footer-margin: 30px;
|
$footer-margin: 30px;
|
||||||
|
|
||||||
$footer-border-color: $header-border-color;
|
|
||||||
|
|
||||||
$separator-border-color: rgba(0, 0, 0, 0.10);
|
$separator-border-color: rgba(0, 0, 0, 0.10);
|
||||||
|
|
||||||
$video-miniature-width: 238px;
|
$video-miniature-width: 238px;
|
||||||
|
|
|
@ -278,6 +278,8 @@ function getIdAndPassAuthPlugins () {
|
||||||
for (const auth of p.idAndPassAuths) {
|
for (const auth of p.idAndPassAuths) {
|
||||||
result.push({
|
result.push({
|
||||||
npmName: p.npmName,
|
npmName: p.npmName,
|
||||||
|
name: p.name,
|
||||||
|
version: p.version,
|
||||||
authName: auth.authName,
|
authName: auth.authName,
|
||||||
weight: auth.getWeight()
|
weight: auth.getWeight()
|
||||||
})
|
})
|
||||||
|
@ -294,6 +296,8 @@ function getExternalAuthsPlugins () {
|
||||||
for (const auth of p.externalAuths) {
|
for (const auth of p.externalAuths) {
|
||||||
result.push({
|
result.push({
|
||||||
npmName: p.npmName,
|
npmName: p.npmName,
|
||||||
|
name: p.name,
|
||||||
|
version: p.version,
|
||||||
authName: auth.authName,
|
authName: auth.authName,
|
||||||
authDisplayName: auth.authDisplayName
|
authDisplayName: auth.authDisplayName
|
||||||
})
|
})
|
||||||
|
|
|
@ -106,14 +106,24 @@ export class PluginManager implements ServerHook {
|
||||||
|
|
||||||
getIdAndPassAuths () {
|
getIdAndPassAuths () {
|
||||||
return this.getRegisteredPlugins()
|
return this.getRegisteredPlugins()
|
||||||
.map(p => ({ npmName: p.npmName, idAndPassAuths: p.registerHelpersStore.getIdAndPassAuths() }))
|
.map(p => ({
|
||||||
|
npmName: p.npmName,
|
||||||
|
name: p.name,
|
||||||
|
version: p.version,
|
||||||
|
idAndPassAuths: p.registerHelpersStore.getIdAndPassAuths()
|
||||||
|
}))
|
||||||
.filter(v => v.idAndPassAuths.length !== 0)
|
.filter(v => v.idAndPassAuths.length !== 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
getExternalAuths () {
|
getExternalAuths () {
|
||||||
return this.getRegisteredPlugins()
|
return this.getRegisteredPlugins()
|
||||||
.map(p => ({ npmName: p.npmName, externalAuths: p.registerHelpersStore.getExternalAuths() }))
|
.map(p => ({
|
||||||
.filter(v => v.externalAuths.length !== 0)
|
npmName: p.npmName,
|
||||||
|
name: p.name,
|
||||||
|
version: p.version,
|
||||||
|
externalAuths: p.registerHelpersStore.getExternalAuths()
|
||||||
|
}))
|
||||||
|
.filter(v => v.externalAuths.length !== 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
getRegisteredSettings (npmName: string) {
|
getRegisteredSettings (npmName: string) {
|
||||||
|
|
|
@ -14,12 +14,16 @@ export interface ServerConfigTheme extends ServerConfigPlugin {
|
||||||
|
|
||||||
export interface RegisteredExternalAuthConfig {
|
export interface RegisteredExternalAuthConfig {
|
||||||
npmName: string
|
npmName: string
|
||||||
|
name: string
|
||||||
|
version: string
|
||||||
authName: string
|
authName: string
|
||||||
authDisplayName: string
|
authDisplayName: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface RegisteredIdAndPassAuthConfig {
|
export interface RegisteredIdAndPassAuthConfig {
|
||||||
npmName: string
|
npmName: string
|
||||||
|
name: string
|
||||||
|
version: string
|
||||||
authName: string
|
authName: string
|
||||||
weight: number
|
weight: number
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue