MOBILE-4201 login: Move oauth and scanQR to login methods component
parent
b8071a6946
commit
ff00454e33
|
@ -1,7 +1,33 @@
|
|||
<ng-container *ngIf="loginMethods?.length">
|
||||
<div *ngIf="loginMethods.length || identityProviders.length || showScanQR"
|
||||
class="ion-text-center ion-padding core-login-site-qrcode-separator">
|
||||
{{ 'core.login.or' | translate }}
|
||||
</div>
|
||||
|
||||
<div class="core-login-methods" *ngIf="loginMethods.length">
|
||||
<ion-button [fill]="'outline'" class="ion-text-wrap ion-margin" *ngFor="let method of loginMethods" (click)="method.action()"
|
||||
[attr.aria-label]="method.name" expand="block">
|
||||
<ion-icon *ngIf="method.icon" [name]="method.icon" slot="start"></ion-icon>
|
||||
<ion-label>{{ method.name }}</ion-label>
|
||||
</ion-button>
|
||||
</div>
|
||||
|
||||
<ng-container *ngIf="showScanQR">
|
||||
<ion-button expand="block" fill="outline" class="ion-margin core-login-site-qrcode" (click)="showInstructionsAndScanQR()">
|
||||
<ion-icon slot="start" name="fas-qrcode" aria-hidden="true"></ion-icon>
|
||||
{{ 'core.scanqr' | translate }}
|
||||
</ion-button>
|
||||
</ng-container>
|
||||
|
||||
<!-- Identity providers. -->
|
||||
<ion-list *ngIf="identityProviders.length" class="ion-padding-top core-login-identity-providers">
|
||||
<ion-item class="ion-text-wrap">
|
||||
<ion-label>
|
||||
<h2 class="item-heading">{{ 'core.login.potentialidps' | translate }}</h2>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
<ion-button [fill]="'outline'" *ngFor="let provider of identityProviders" class="ion-text-wrap ion-margin core-oauth-provider"
|
||||
(click)="oauthClicked(provider)" [attr.aria-label]="provider.name" expand="block">
|
||||
<img *ngIf="provider.iconurl" [src]="provider.iconurl" alt="" width="32" height="32" slot="start" aria-hidden="true">
|
||||
<ion-label>{{ provider.name }}</ion-label>
|
||||
</ion-button>
|
||||
</ion-list>
|
||||
|
|
|
@ -12,9 +12,12 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { Component, Input, OnInit } from '@angular/core';
|
||||
import { CoreSiteIdentityProvider, CoreSitePublicConfigResponse } from '@classes/site';
|
||||
import { CoreLoginHelper, CoreLoginMethod } from '@features/login/services/login-helper';
|
||||
import { CoreRedirectPayload } from '@services/navigator';
|
||||
import { CoreSites } from '@services/sites';
|
||||
import { CoreDomUtils } from '@services/utils/dom';
|
||||
|
||||
@Component({
|
||||
selector: 'core-login-methods',
|
||||
|
@ -23,18 +26,75 @@ import { CoreSites } from '@services/sites';
|
|||
})
|
||||
export class CoreLoginMethodsComponent implements OnInit {
|
||||
|
||||
loginMethods?: CoreLoginMethod[];
|
||||
@Input() reconnect = false;
|
||||
@Input() siteUrl = '';
|
||||
@Input() siteConfig?: CoreSitePublicConfigResponse;
|
||||
@Input() redirectData?: CoreRedirectPayload;
|
||||
|
||||
showScanQR = false;
|
||||
loginMethods: CoreLoginMethod[] = [];
|
||||
identityProviders: CoreSiteIdentityProvider[] = [];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
async ngOnInit(): Promise<void> {
|
||||
this.loginMethods = await CoreLoginHelper.getLoginMethods();
|
||||
const currentSite = CoreSites.getCurrentSite();
|
||||
const defaultMethod = await CoreLoginHelper.getDefaultLoginMethod();
|
||||
if (this.reconnect) {
|
||||
this.loginMethods = await CoreLoginHelper.getLoginMethods();
|
||||
|
||||
if (currentSite?.isLoggedOut() && defaultMethod) {
|
||||
await defaultMethod.action();
|
||||
const currentSite = CoreSites.getCurrentSite();
|
||||
const defaultMethod = await CoreLoginHelper.getDefaultLoginMethod();
|
||||
if (currentSite?.isLoggedOut() && defaultMethod) {
|
||||
await defaultMethod.action();
|
||||
}
|
||||
}
|
||||
|
||||
if (this.siteConfig) {
|
||||
const disabledFeatures = CoreLoginHelper.getDisabledFeatures(this.siteConfig);
|
||||
|
||||
this.identityProviders = CoreLoginHelper.getValidIdentityProviders(this.siteConfig, disabledFeatures);
|
||||
|
||||
if (this.reconnect) {
|
||||
this.showScanQR = CoreLoginHelper.displayQRInSiteScreen();
|
||||
}
|
||||
|
||||
// If still false or credentials screen.
|
||||
if (!this.reconnect || !this.showScanQR) {
|
||||
this.showScanQR = await CoreLoginHelper.displayQRInCredentialsScreen(this.siteConfig.tool_mobile_qrcodetype);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Show instructions and scan QR code.
|
||||
*
|
||||
* @returns Promise resolved when done.
|
||||
*/
|
||||
async showInstructionsAndScanQR(): Promise<void> {
|
||||
try {
|
||||
await CoreLoginHelper.showScanQRInstructions();
|
||||
|
||||
await CoreLoginHelper.scanQR();
|
||||
} catch {
|
||||
// Ignore errors.
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An OAuth button was clicked.
|
||||
*
|
||||
* @param provider The provider that was clicked.
|
||||
*/
|
||||
oauthClicked(provider: CoreSiteIdentityProvider): void {
|
||||
const result = CoreLoginHelper.openBrowserForOAuthLogin(
|
||||
this.siteUrl,
|
||||
provider,
|
||||
this.siteConfig?.launchurl,
|
||||
this.redirectData,
|
||||
);
|
||||
|
||||
if (!result) {
|
||||
CoreDomUtils.showErrorModal('Invalid data.');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -59,14 +59,6 @@
|
|||
</ion-button>
|
||||
<!-- Remove this once Ionic fixes this bug: https://github.com/ionic-team/ionic-framework/issues/19368 -->
|
||||
<input type="submit" class="core-submit-hidden-enter" />
|
||||
|
||||
<ng-container *ngIf="showScanQR">
|
||||
<div class="ion-text-center ion-padding core-login-site-qrcode-separator">{{ 'core.login.or' | translate }}</div>
|
||||
<ion-button expand="block" fill="outline" class="ion-margin core-login-site-qrcode" (click)="showInstructionsAndScanQR()">
|
||||
<ion-icon slot="start" name="fas-qrcode" aria-hidden="true"></ion-icon>
|
||||
{{ 'core.scanqr' | translate }}
|
||||
</ion-button>
|
||||
</ng-container>
|
||||
</form>
|
||||
|
||||
<!-- Forgotten password option. -->
|
||||
|
@ -75,18 +67,7 @@
|
|||
{{ 'core.login.forgotten' | translate }}
|
||||
</ion-button>
|
||||
|
||||
<ion-list *ngIf="identityProviders && identityProviders.length" class="ion-padding-top core-login-identity-providers">
|
||||
<ion-item class="ion-text-wrap">
|
||||
<ion-label>
|
||||
<h2 class="item-heading">{{ 'core.login.potentialidps' | translate }}</h2>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
<ion-button fill="outline" *ngFor="let provider of identityProviders" class="ion-text-wrap ion-margin core-oauth-provider"
|
||||
(click)="oauthClicked(provider)" [attr.aria-label]="provider.name" expand="block">
|
||||
<img *ngIf="provider.iconurl" [src]="provider.iconurl" alt="" width="32" height="32" slot="start" aria-hidden="true">
|
||||
<ion-label>{{provider.name}}</ion-label>
|
||||
</ion-button>
|
||||
</ion-list>
|
||||
<core-login-methods *ngIf="siteConfig" [siteConfig]="siteConfig" [siteUrl]="siteUrl"></core-login-methods>
|
||||
|
||||
<ion-list *ngIf="canSignup || authInstructions" class="ion-padding-top core-login-sign-up">
|
||||
<ion-item class="ion-text-wrap">
|
||||
|
|
|
@ -24,7 +24,7 @@ import { CoreDomUtils } from '@services/utils/dom';
|
|||
import { CoreLoginHelper } from '@features/login/services/login-helper';
|
||||
import { CoreConstants } from '@/core/constants';
|
||||
import { Translate } from '@singletons';
|
||||
import { CoreSiteIdentityProvider, CoreSitePublicConfigResponse } from '@classes/site';
|
||||
import { CoreSitePublicConfigResponse } from '@classes/site';
|
||||
import { CoreEvents } from '@singletons/events';
|
||||
import { CoreNavigator } from '@services/navigator';
|
||||
import { CoreForms } from '@singletons/form';
|
||||
|
@ -53,7 +53,6 @@ export class CoreLoginCredentialsPage implements OnInit, OnDestroy {
|
|||
logoUrl?: string;
|
||||
authInstructions?: string;
|
||||
canSignup?: boolean;
|
||||
identityProviders?: CoreSiteIdentityProvider[];
|
||||
pageLoaded = false;
|
||||
isBrowserSSO = false;
|
||||
showForgottenPassword = true;
|
||||
|
@ -206,7 +205,6 @@ export class CoreLoginCredentialsPage implements OnInit, OnDestroy {
|
|||
this.showScanQR = await CoreLoginHelper.displayQRInCredentialsScreen(this.siteConfig.tool_mobile_qrcodetype);
|
||||
|
||||
const disabledFeatures = CoreLoginHelper.getDisabledFeatures(this.siteConfig);
|
||||
this.identityProviders = CoreLoginHelper.getValidIdentityProviders(this.siteConfig, disabledFeatures);
|
||||
this.canSignup = this.siteConfig.registerauth == 'email' &&
|
||||
!CoreLoginHelper.isEmailSignupDisabled(this.siteConfig, disabledFeatures);
|
||||
this.showForgottenPassword = !CoreLoginHelper.isForgottenPasswordDisabled(this.siteConfig, disabledFeatures);
|
||||
|
@ -222,7 +220,6 @@ export class CoreLoginCredentialsPage implements OnInit, OnDestroy {
|
|||
} else {
|
||||
this.authInstructions = undefined;
|
||||
this.canSignup = false;
|
||||
this.identityProviders = [];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -329,32 +326,6 @@ export class CoreLoginCredentialsPage implements OnInit, OnDestroy {
|
|||
CoreLoginHelper.forgottenPasswordClicked(this.siteUrl, this.credForm.value.username, this.siteConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
* An OAuth button was clicked.
|
||||
*
|
||||
* @param provider The provider that was clicked.
|
||||
*/
|
||||
oauthClicked(provider: CoreSiteIdentityProvider): void {
|
||||
if (!CoreLoginHelper.openBrowserForOAuthLogin(this.siteUrl, provider, this.siteConfig?.launchurl)) {
|
||||
CoreDomUtils.showErrorModal('Invalid data.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Show instructions and scan QR code.
|
||||
*
|
||||
* @returns Promise resolved when done.
|
||||
*/
|
||||
async showInstructionsAndScanQR(): Promise<void> {
|
||||
try {
|
||||
await CoreLoginHelper.showScanQRInstructions();
|
||||
|
||||
await CoreLoginHelper.scanQR();
|
||||
} catch {
|
||||
// Ignore errors.
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Open email signup page.
|
||||
*/
|
||||
|
@ -370,7 +341,7 @@ export class CoreLoginCredentialsPage implements OnInit, OnDestroy {
|
|||
}
|
||||
|
||||
/**
|
||||
* View destroyed.
|
||||
* @inheritdoc
|
||||
*/
|
||||
ngOnDestroy(): void {
|
||||
this.viewLeft = true;
|
||||
|
|
|
@ -83,37 +83,11 @@
|
|||
class="core-login-forgotten-password core-button-as-link ion-text-wrap" (click)="forgottenPassword()">
|
||||
{{ 'core.login.forgotten' | translate }}
|
||||
</ion-button>
|
||||
|
||||
<div class="ion-text-center ion-padding core-login-site-qrcode-separator">{{ 'core.login.or' | translate }}</div>
|
||||
|
||||
<!-- Login methods -->
|
||||
<core-login-methods></core-login-methods>
|
||||
|
||||
<ng-container *ngIf="showScanQR && !isBrowserSSO">
|
||||
<ion-button expand="block" fill="outline" class="ion-margin core-login-site-qrcode"
|
||||
(click)="showInstructionsAndScanQR()">
|
||||
<ion-icon slot="start" name="fas-qrcode" aria-hidden="true"></ion-icon>
|
||||
{{ 'core.scanqr' | translate }}
|
||||
</ion-button>
|
||||
</ng-container>
|
||||
</form>
|
||||
|
||||
|
||||
|
||||
<!-- Identity providers. -->
|
||||
<ion-list *ngIf="identityProviders?.length" class="ion-padding-top core-login-identity-providers">
|
||||
<ion-item class="ion-text-wrap">
|
||||
<ion-label>
|
||||
<h2 class="item-heading">{{ 'core.login.potentialidps' | translate }}</h2>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
<ion-button [fill]="'outline'" *ngFor="let provider of identityProviders"
|
||||
class="ion-text-wrap ion-margin core-oauth-provider" (click)="oauthClicked(provider)" [attr.aria-label]="provider.name"
|
||||
expand="block">
|
||||
<img *ngIf="provider.iconurl" [src]="provider.iconurl" alt="" width="32" height="32" slot="start" aria-hidden="true">
|
||||
<ion-label>{{ provider.name }}</ion-label>
|
||||
</ion-button>
|
||||
</ion-list>
|
||||
<!-- Additional Login methods -->
|
||||
<core-login-methods *ngIf="siteConfig" [siteConfig]="siteConfig" [reconnect]="true" [siteUrl]="siteUrl"
|
||||
[redirectData]="redirectData"></core-login-methods>
|
||||
|
||||
<!-- If OAuth, display cancel button since the form isn't displayed. -->
|
||||
<ion-list *ngIf="isOAuth">
|
||||
|
|
|
@ -21,7 +21,7 @@ import { CoreSiteBasicInfo, CoreSites, CoreSitesReadingStrategy } from '@service
|
|||
import { CoreDomUtils } from '@services/utils/dom';
|
||||
import { CoreUtils } from '@services/utils/utils';
|
||||
import { CoreLoginHelper } from '@features/login/services/login-helper';
|
||||
import { CoreSite, CoreSiteIdentityProvider, CoreSitePublicConfigResponse } from '@classes/site';
|
||||
import { CoreSite, CoreSitePublicConfigResponse } from '@classes/site';
|
||||
import { CoreEvents } from '@singletons/events';
|
||||
import { CoreError } from '@classes/errors/error';
|
||||
import { CoreNavigator, CoreRedirectPayload } from '@services/navigator';
|
||||
|
@ -46,9 +46,7 @@ export class CoreLoginReconnectPage implements OnInit, OnDestroy {
|
|||
|
||||
credForm: FormGroup;
|
||||
siteUrl!: string;
|
||||
username!: string;
|
||||
logoUrl?: string;
|
||||
identityProviders?: CoreSiteIdentityProvider[];
|
||||
showForgottenPassword = true;
|
||||
showUserAvatar = false;
|
||||
isBrowserSSO = false;
|
||||
|
@ -61,12 +59,13 @@ export class CoreLoginReconnectPage implements OnInit, OnDestroy {
|
|||
reconnectAttempts = 0;
|
||||
supportConfig?: CoreUserSupportConfig;
|
||||
exceededAttemptsHTML?: SafeHtml | string | null;
|
||||
siteConfig?: CoreSitePublicConfigResponse;
|
||||
redirectData?: CoreRedirectPayload;
|
||||
|
||||
protected siteConfig?: CoreSitePublicConfigResponse;
|
||||
protected viewLeft = false;
|
||||
protected eventThrown = false;
|
||||
protected redirectData?: CoreRedirectPayload;
|
||||
protected loginSuccessful = false;
|
||||
protected username = '';
|
||||
|
||||
constructor(
|
||||
protected fb: FormBuilder,
|
||||
|
@ -127,7 +126,7 @@ export class CoreLoginReconnectPage implements OnInit, OnDestroy {
|
|||
// Show logo instead of avatar if it's a fixed site.
|
||||
this.showUserAvatar = !availableSites.length;
|
||||
|
||||
this.checkSiteConfig(site);
|
||||
await this.checkSiteConfig(site);
|
||||
|
||||
this.showLoading = false;
|
||||
} catch (error) {
|
||||
|
@ -175,9 +174,6 @@ export class CoreLoginReconnectPage implements OnInit, OnDestroy {
|
|||
return;
|
||||
}
|
||||
|
||||
const disabledFeatures = CoreLoginHelper.getDisabledFeatures(this.siteConfig);
|
||||
|
||||
this.identityProviders = CoreLoginHelper.getValidIdentityProviders(this.siteConfig, disabledFeatures);
|
||||
this.showForgottenPassword = !CoreLoginHelper.isForgottenPasswordDisabled(this.siteConfig);
|
||||
this.exceededAttemptsHTML = CoreLoginHelper.buildExceededAttemptsHTML(
|
||||
!!this.supportConfig?.canContactSupport(),
|
||||
|
@ -191,12 +187,6 @@ export class CoreLoginReconnectPage implements OnInit, OnDestroy {
|
|||
|
||||
this.isBrowserSSO = !this.isOAuth && CoreLoginHelper.isSSOLoginNeeded(this.siteConfig.typeoflogin);
|
||||
|
||||
this.showScanQR = CoreLoginHelper.displayQRInSiteScreen();
|
||||
|
||||
if (!this.showScanQR) {
|
||||
this.showScanQR = await CoreLoginHelper.displayQRInCredentialsScreen(this.siteConfig.tool_mobile_qrcodetype);
|
||||
}
|
||||
|
||||
await CoreSites.checkApplication(this.siteConfig);
|
||||
|
||||
this.logoUrl = CoreLoginHelper.getLogoUrl(this.siteConfig);
|
||||
|
@ -324,39 +314,6 @@ export class CoreLoginReconnectPage implements OnInit, OnDestroy {
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* An OAuth button was clicked.
|
||||
*
|
||||
* @param provider The provider that was clicked.
|
||||
*/
|
||||
oauthClicked(provider: CoreSiteIdentityProvider): void {
|
||||
const result = CoreLoginHelper.openBrowserForOAuthLogin(
|
||||
this.siteUrl,
|
||||
provider,
|
||||
this.siteConfig?.launchurl,
|
||||
this.redirectData,
|
||||
);
|
||||
|
||||
if (!result) {
|
||||
CoreDomUtils.showErrorModal('Invalid data.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Show instructions and scan QR code.
|
||||
*
|
||||
* @returns Promise resolved when done.
|
||||
*/
|
||||
async showInstructionsAndScanQR(): Promise<void> {
|
||||
try {
|
||||
await CoreLoginHelper.showScanQRInstructions();
|
||||
|
||||
await CoreLoginHelper.scanQR();
|
||||
} catch {
|
||||
// Ignore errors.
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A11y key functionality that prevents keyDown events.
|
||||
*
|
||||
|
|
|
@ -975,6 +975,7 @@ export class CoreLoginHelperProvider {
|
|||
} else {
|
||||
if (currentSite.isOAuth()) {
|
||||
// User authenticated using an OAuth method. Check if it's still valid.
|
||||
// @TODO Why disabledFeatures is not checked here?
|
||||
const identityProviders = this.getValidIdentityProviders(result.config);
|
||||
const providerToUse = identityProviders.find((provider) => {
|
||||
const params = CoreUrlUtils.extractUrlParams(provider.url);
|
||||
|
|
Loading…
Reference in New Issue