mirror of
https://github.com/discourse/discourse.git
synced 2025-05-29 21:40:26 +08:00
FIX: Automatic auth flow with full page login/signup (#30928)
Co-authored-by: Penar Musaraj <pmusaraj@gmail.com>
This commit is contained in:
@ -140,14 +140,18 @@ export default {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (siteSettings.full_page_login) {
|
if (siteSettings.full_page_login) {
|
||||||
router.transitionTo("signup").then((signup) => {
|
router
|
||||||
const signupController =
|
.transitionTo("signup", {
|
||||||
signup.controller || owner.lookup("controller:signup");
|
queryParams: { authComplete: true },
|
||||||
Object.keys(createAccountProps || {}).forEach((key) => {
|
})
|
||||||
signupController.set(key, createAccountProps[key]);
|
.then((signup) => {
|
||||||
|
const signupController =
|
||||||
|
signup.controller || owner.lookup("controller:signup");
|
||||||
|
Object.keys(createAccountProps || {}).forEach((key) => {
|
||||||
|
signupController.set(key, createAccountProps[key]);
|
||||||
|
});
|
||||||
|
signupController.handleSkipConfirmation();
|
||||||
});
|
});
|
||||||
signupController.handleSkipConfirmation();
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
modal.show(CreateAccount, { model: createAccountProps });
|
modal.show(CreateAccount, { model: createAccountProps });
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,6 @@ import DiscourseURL from "discourse/lib/url";
|
|||||||
import { postRNWebviewMessage } from "discourse/lib/utilities";
|
import { postRNWebviewMessage } from "discourse/lib/utilities";
|
||||||
import Category from "discourse/models/category";
|
import Category from "discourse/models/category";
|
||||||
import Composer from "discourse/models/composer";
|
import Composer from "discourse/models/composer";
|
||||||
import { findAll } from "discourse/models/login-method";
|
|
||||||
import DiscourseRoute from "discourse/routes/discourse";
|
import DiscourseRoute from "discourse/routes/discourse";
|
||||||
import { i18n } from "discourse-i18n";
|
import { i18n } from "discourse-i18n";
|
||||||
|
|
||||||
@ -44,17 +43,6 @@ export default class ApplicationRoute extends DiscourseRoute {
|
|||||||
@setting("title") siteTitle;
|
@setting("title") siteTitle;
|
||||||
@setting("short_site_description") shortSiteDescription;
|
@setting("short_site_description") shortSiteDescription;
|
||||||
|
|
||||||
get isOnlyOneExternalLoginMethod() {
|
|
||||||
return (
|
|
||||||
!this.siteSettings.enable_local_logins &&
|
|
||||||
this.externalLoginMethods.length === 1
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
get externalLoginMethods() {
|
|
||||||
return findAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
@action
|
@action
|
||||||
loading(transition) {
|
loading(transition) {
|
||||||
this.loadingSlider.transitionStarted();
|
this.loadingSlider.transitionStarted();
|
||||||
@ -295,8 +283,8 @@ export default class ApplicationRoute extends DiscourseRoute {
|
|||||||
: encodeURIComponent(window.location.pathname);
|
: encodeURIComponent(window.location.pathname);
|
||||||
window.location = getURL("/session/sso?return_path=" + returnPath);
|
window.location = getURL("/session/sso?return_path=" + returnPath);
|
||||||
} else {
|
} else {
|
||||||
if (this.isOnlyOneExternalLoginMethod) {
|
if (this.login.isOnlyOneExternalLoginMethod) {
|
||||||
this.login.externalLogin(this.externalLoginMethods[0]);
|
this.login.singleExternalLogin();
|
||||||
} else if (this.siteSettings.full_page_login) {
|
} else if (this.siteSettings.full_page_login) {
|
||||||
this.router.transitionTo("login").then((login) => {
|
this.router.transitionTo("login").then((login) => {
|
||||||
login.controller.set("canSignUp", this.controller.canSignUp);
|
login.controller.set("canSignUp", this.controller.canSignUp);
|
||||||
@ -321,11 +309,9 @@ export default class ApplicationRoute extends DiscourseRoute {
|
|||||||
const returnPath = encodeURIComponent(window.location.pathname);
|
const returnPath = encodeURIComponent(window.location.pathname);
|
||||||
window.location = getURL("/session/sso?return_path=" + returnPath);
|
window.location = getURL("/session/sso?return_path=" + returnPath);
|
||||||
} else {
|
} else {
|
||||||
if (this.isOnlyOneExternalLoginMethod) {
|
if (this.login.isOnlyOneExternalLoginMethod) {
|
||||||
// we will automatically redirect to the external auth service
|
// we will automatically redirect to the external auth service
|
||||||
this.login.externalLogin(this.externalLoginMethods[0], {
|
this.login.singleExternalLogin({ signup: true });
|
||||||
signup: true,
|
|
||||||
});
|
|
||||||
} else if (this.siteSettings.full_page_login) {
|
} else if (this.siteSettings.full_page_login) {
|
||||||
this.router.transitionTo("signup").then((signup) => {
|
this.router.transitionTo("signup").then((signup) => {
|
||||||
Object.keys(createAccountProps || {}).forEach((key) => {
|
Object.keys(createAccountProps || {}).forEach((key) => {
|
||||||
|
@ -7,9 +7,12 @@ import DiscourseRoute from "discourse/routes/discourse";
|
|||||||
export default class LoginRoute extends DiscourseRoute {
|
export default class LoginRoute extends DiscourseRoute {
|
||||||
@service siteSettings;
|
@service siteSettings;
|
||||||
@service router;
|
@service router;
|
||||||
|
@service login;
|
||||||
|
|
||||||
beforeModel() {
|
beforeModel() {
|
||||||
if (
|
if (this.login.isOnlyOneExternalLoginMethod) {
|
||||||
|
this.login.singleExternalLogin();
|
||||||
|
} else if (
|
||||||
!this.siteSettings.login_required &&
|
!this.siteSettings.login_required &&
|
||||||
(!this.siteSettings.full_page_login ||
|
(!this.siteSettings.full_page_login ||
|
||||||
this.siteSettings.enable_discourse_connect)
|
this.siteSettings.enable_discourse_connect)
|
||||||
@ -35,6 +38,10 @@ export default class LoginRoute extends DiscourseRoute {
|
|||||||
controller.set("flashType", "");
|
controller.set("flashType", "");
|
||||||
controller.set("flash", "");
|
controller.set("flash", "");
|
||||||
|
|
||||||
|
if (this.login.isOnlyOneExternalLoginMethod) {
|
||||||
|
controller.set("isRedirecting", true);
|
||||||
|
}
|
||||||
|
|
||||||
if (this.siteSettings.login_required) {
|
if (this.siteSettings.login_required) {
|
||||||
controller.set("showLogin", false);
|
controller.set("showLogin", false);
|
||||||
}
|
}
|
||||||
|
@ -4,11 +4,28 @@ import { service } from "@ember/service";
|
|||||||
import DiscourseRoute from "discourse/routes/discourse";
|
import DiscourseRoute from "discourse/routes/discourse";
|
||||||
|
|
||||||
export default class SignupRoute extends DiscourseRoute {
|
export default class SignupRoute extends DiscourseRoute {
|
||||||
@service router;
|
|
||||||
@service siteSettings;
|
@service siteSettings;
|
||||||
|
@service router;
|
||||||
|
@service login;
|
||||||
|
|
||||||
beforeModel() {
|
authComplete = false;
|
||||||
this.showCreateAccount();
|
|
||||||
|
beforeModel(transition) {
|
||||||
|
this.authComplete = transition.to.queryParams.authComplete || false;
|
||||||
|
|
||||||
|
if (this.login.isOnlyOneExternalLoginMethod && !this.authComplete) {
|
||||||
|
this.login.singleExternalLogin({ signup: true });
|
||||||
|
} else {
|
||||||
|
this.showCreateAccount();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setupController(controller) {
|
||||||
|
super.setupController(...arguments);
|
||||||
|
|
||||||
|
if (this.login.isOnlyOneExternalLoginMethod && !this.authComplete) {
|
||||||
|
controller.set("isRedirecting", true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
|
@ -1,9 +1,12 @@
|
|||||||
import { action } from "@ember/object";
|
import { action } from "@ember/object";
|
||||||
import Service from "@ember/service";
|
import Service, { service } from "@ember/service";
|
||||||
import { disableImplicitInjections } from "discourse/lib/implicit-injections";
|
import { disableImplicitInjections } from "discourse/lib/implicit-injections";
|
||||||
|
import { findAll } from "discourse/models/login-method";
|
||||||
|
|
||||||
@disableImplicitInjections
|
@disableImplicitInjections
|
||||||
export default class LoginService extends Service {
|
export default class LoginService extends Service {
|
||||||
|
@service siteSettings;
|
||||||
|
|
||||||
@action
|
@action
|
||||||
async externalLogin(
|
async externalLogin(
|
||||||
loginMethod,
|
loginMethod,
|
||||||
@ -16,4 +19,20 @@ export default class LoginService extends Service {
|
|||||||
setLoggingIn?.(false);
|
setLoggingIn?.(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@action
|
||||||
|
async singleExternalLogin(opts) {
|
||||||
|
await this.externalLogin(this.externalLoginMethods[0], opts);
|
||||||
|
}
|
||||||
|
|
||||||
|
get isOnlyOneExternalLoginMethod() {
|
||||||
|
return (
|
||||||
|
!this.siteSettings.enable_local_logins &&
|
||||||
|
this.externalLoginMethods.length === 1
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
get externalLoginMethods() {
|
||||||
|
return findAll();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,176 +1,183 @@
|
|||||||
{{#if
|
{{hide-application-sidebar}}
|
||||||
(and
|
{{body-class "login-page"}}
|
||||||
this.siteSettings.full_page_login
|
|
||||||
(or this.showLogin (not this.siteSettings.login_required))
|
|
||||||
)
|
|
||||||
}}
|
|
||||||
{{hide-application-header-buttons "search" "login" "signup" "menu"}}
|
|
||||||
{{hide-application-sidebar}}
|
|
||||||
{{body-class "login-page"}}
|
|
||||||
<div class="login-fullpage">
|
|
||||||
<FlashMessage @flash={{this.flash}} @type={{this.flashType}} />
|
|
||||||
|
|
||||||
<div class={{concat-class "login-body" this.bodyClasses}}>
|
{{#if this.isRedirecting}}
|
||||||
<PluginOutlet @name="login-before-modal-body" @connectorTagName="div" />
|
{{loading-spinner}}
|
||||||
|
{{else}}
|
||||||
|
{{#if
|
||||||
|
(and
|
||||||
|
this.siteSettings.full_page_login
|
||||||
|
(or this.showLogin (not this.siteSettings.login_required))
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
{{hide-application-header-buttons "search" "login" "signup" "menu"}}
|
||||||
|
<div class="login-fullpage">
|
||||||
|
<FlashMessage @flash={{this.flash}} @type={{this.flashType}} />
|
||||||
|
|
||||||
{{#if this.hasNoLoginOptions}}
|
<div class={{concat-class "login-body" this.bodyClasses}}>
|
||||||
<div class={{if this.site.desktopView "login-left-side"}}>
|
<PluginOutlet @name="login-before-modal-body" @connectorTagName="div" />
|
||||||
<div class="login-welcome-header no-login-methods-configured">
|
|
||||||
<h1 class="login-title">{{i18n "login.no_login_methods.title"}}</h1>
|
|
||||||
<img />
|
|
||||||
<p class="login-subheader">
|
|
||||||
{{html-safe
|
|
||||||
(i18n
|
|
||||||
"login.no_login_methods.description"
|
|
||||||
(hash adminLoginPath=this.adminLoginPath)
|
|
||||||
)
|
|
||||||
}}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{else}}
|
|
||||||
{{#if this.site.mobileView}}
|
|
||||||
<WelcomeHeader @header={{i18n "login.header_title"}}>
|
|
||||||
<PluginOutlet
|
|
||||||
@name="login-header-bottom"
|
|
||||||
@outletArgs={{hash createAccount=this.createAccount}}
|
|
||||||
/>
|
|
||||||
</WelcomeHeader>
|
|
||||||
{{#if this.showLoginButtons}}
|
|
||||||
<LoginButtons
|
|
||||||
@externalLogin={{this.externalLoginAction}}
|
|
||||||
@passkeyLogin={{this.passkeyLogin}}
|
|
||||||
@context="login"
|
|
||||||
/>
|
|
||||||
{{/if}}
|
|
||||||
{{/if}}
|
|
||||||
|
|
||||||
{{#if this.canLoginLocal}}
|
{{#if this.hasNoLoginOptions}}
|
||||||
<div class={{if this.site.desktopView "login-left-side"}}>
|
<div class={{if this.site.desktopView "login-left-side"}}>
|
||||||
{{#if this.site.desktopView}}
|
<div class="login-welcome-header no-login-methods-configured">
|
||||||
<WelcomeHeader @header={{i18n "login.header_title"}}>
|
<h1 class="login-title">{{i18n
|
||||||
<PluginOutlet
|
"login.no_login_methods.title"
|
||||||
@name="login-header-bottom"
|
}}</h1>
|
||||||
@outletArgs={{hash createAccount=this.createAccount}}
|
<img />
|
||||||
/>
|
<p class="login-subheader">
|
||||||
</WelcomeHeader>
|
{{html-safe
|
||||||
{{/if}}
|
(i18n
|
||||||
<LocalLoginForm
|
"login.no_login_methods.description"
|
||||||
@loginName={{this.loginName}}
|
(hash adminLoginPath=this.adminLoginPath)
|
||||||
@loginNameChanged={{this.loginNameChanged}}
|
)
|
||||||
@canLoginLocalWithEmail={{this.canLoginLocalWithEmail}}
|
}}
|
||||||
@canUsePasskeys={{this.canUsePasskeys}}
|
</p>
|
||||||
@passkeyLogin={{this.passkeyLogin}}
|
|
||||||
@loginPassword={{this.loginPassword}}
|
|
||||||
@secondFactorMethod={{this.secondFactorMethod}}
|
|
||||||
@secondFactorToken={{this.secondFactorToken}}
|
|
||||||
@backupEnabled={{this.backupEnabled}}
|
|
||||||
@totpEnabled={{this.totpEnabled}}
|
|
||||||
@securityKeyAllowedCredentialIds={{this.securityKeyAllowedCredentialIds}}
|
|
||||||
@securityKeyChallenge={{this.securityKeyChallenge}}
|
|
||||||
@showSecurityKey={{this.showSecurityKey}}
|
|
||||||
@otherMethodAllowed={{this.otherMethodAllowed}}
|
|
||||||
@showSecondFactor={{this.showSecondFactor}}
|
|
||||||
@handleForgotPassword={{this.handleForgotPassword}}
|
|
||||||
@login={{this.triggerLogin}}
|
|
||||||
@flashChanged={{this.flashChanged}}
|
|
||||||
@flashTypeChanged={{this.flashTypeChanged}}
|
|
||||||
@securityKeyCredentialChanged={{this.securityKeyCredentialChanged}}
|
|
||||||
/>
|
|
||||||
{{#if this.site.desktopView}}
|
|
||||||
<LoginPageCta
|
|
||||||
@canLoginLocal={{this.canLoginLocal}}
|
|
||||||
@showSecurityKey={{this.showSecurityKey}}
|
|
||||||
@login={{this.triggerLogin}}
|
|
||||||
@loginButtonLabel={{this.loginButtonLabel}}
|
|
||||||
@loginDisabled={{this.loginDisabled}}
|
|
||||||
@showSignupLink={{this.showSignupLink}}
|
|
||||||
@createAccount={{this.createAccount}}
|
|
||||||
@loggingIn={{this.loggingIn}}
|
|
||||||
@showSecondFactor={{this.showSecondFactor}}
|
|
||||||
/>
|
|
||||||
{{/if}}
|
|
||||||
</div>
|
|
||||||
{{/if}}
|
|
||||||
|
|
||||||
{{#if (and this.showLoginButtons this.site.desktopView)}}
|
|
||||||
{{#unless this.canLoginLocal}}
|
|
||||||
<div class="login-left-side">
|
|
||||||
<WelcomeHeader @header={{i18n "login.header_title"}} />
|
|
||||||
</div>
|
</div>
|
||||||
{{/unless}}
|
</div>
|
||||||
{{#if this.hasAtLeastOneLoginButton}}
|
{{else}}
|
||||||
<div class="login-right-side">
|
{{#if this.site.mobileView}}
|
||||||
|
<WelcomeHeader @header={{i18n "login.header_title"}}>
|
||||||
|
<PluginOutlet
|
||||||
|
@name="login-header-bottom"
|
||||||
|
@outletArgs={{hash createAccount=this.createAccount}}
|
||||||
|
/>
|
||||||
|
</WelcomeHeader>
|
||||||
|
{{#if this.showLoginButtons}}
|
||||||
<LoginButtons
|
<LoginButtons
|
||||||
@externalLogin={{this.externalLoginAction}}
|
@externalLogin={{this.externalLoginAction}}
|
||||||
@passkeyLogin={{this.passkeyLogin}}
|
@passkeyLogin={{this.passkeyLogin}}
|
||||||
@context="login"
|
@context="login"
|
||||||
/>
|
/>
|
||||||
|
{{/if}}
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if this.canLoginLocal}}
|
||||||
|
<div class={{if this.site.desktopView "login-left-side"}}>
|
||||||
|
{{#if this.site.desktopView}}
|
||||||
|
<WelcomeHeader @header={{i18n "login.header_title"}}>
|
||||||
|
<PluginOutlet
|
||||||
|
@name="login-header-bottom"
|
||||||
|
@outletArgs={{hash createAccount=this.createAccount}}
|
||||||
|
/>
|
||||||
|
</WelcomeHeader>
|
||||||
|
{{/if}}
|
||||||
|
<LocalLoginForm
|
||||||
|
@loginName={{this.loginName}}
|
||||||
|
@loginNameChanged={{this.loginNameChanged}}
|
||||||
|
@canLoginLocalWithEmail={{this.canLoginLocalWithEmail}}
|
||||||
|
@canUsePasskeys={{this.canUsePasskeys}}
|
||||||
|
@passkeyLogin={{this.passkeyLogin}}
|
||||||
|
@loginPassword={{this.loginPassword}}
|
||||||
|
@secondFactorMethod={{this.secondFactorMethod}}
|
||||||
|
@secondFactorToken={{this.secondFactorToken}}
|
||||||
|
@backupEnabled={{this.backupEnabled}}
|
||||||
|
@totpEnabled={{this.totpEnabled}}
|
||||||
|
@securityKeyAllowedCredentialIds={{this.securityKeyAllowedCredentialIds}}
|
||||||
|
@securityKeyChallenge={{this.securityKeyChallenge}}
|
||||||
|
@showSecurityKey={{this.showSecurityKey}}
|
||||||
|
@otherMethodAllowed={{this.otherMethodAllowed}}
|
||||||
|
@showSecondFactor={{this.showSecondFactor}}
|
||||||
|
@handleForgotPassword={{this.handleForgotPassword}}
|
||||||
|
@login={{this.triggerLogin}}
|
||||||
|
@flashChanged={{this.flashChanged}}
|
||||||
|
@flashTypeChanged={{this.flashTypeChanged}}
|
||||||
|
@securityKeyCredentialChanged={{this.securityKeyCredentialChanged}}
|
||||||
|
/>
|
||||||
|
{{#if this.site.desktopView}}
|
||||||
|
<LoginPageCta
|
||||||
|
@canLoginLocal={{this.canLoginLocal}}
|
||||||
|
@showSecurityKey={{this.showSecurityKey}}
|
||||||
|
@login={{this.triggerLogin}}
|
||||||
|
@loginButtonLabel={{this.loginButtonLabel}}
|
||||||
|
@loginDisabled={{this.loginDisabled}}
|
||||||
|
@showSignupLink={{this.showSignupLink}}
|
||||||
|
@createAccount={{this.createAccount}}
|
||||||
|
@loggingIn={{this.loggingIn}}
|
||||||
|
@showSecondFactor={{this.showSecondFactor}}
|
||||||
|
/>
|
||||||
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{/if}}
|
|
||||||
{{/if}}
|
|
||||||
|
|
||||||
{{#if this.site.mobileView}}
|
{{#if (and this.showLoginButtons this.site.desktopView)}}
|
||||||
{{#unless this.hasNoLoginOptions}}
|
{{#unless this.canLoginLocal}}
|
||||||
<LoginPageCta
|
<div class="login-left-side">
|
||||||
@canLoginLocal={{this.canLoginLocal}}
|
<WelcomeHeader @header={{i18n "login.header_title"}} />
|
||||||
@showSecurityKey={{this.showSecurityKey}}
|
</div>
|
||||||
@login={{this.triggerLogin}}
|
{{/unless}}
|
||||||
@loginButtonLabel={{this.loginButtonLabel}}
|
{{#if this.hasAtLeastOneLoginButton}}
|
||||||
@loginDisabled={{this.loginDisabled}}
|
<div class="login-right-side">
|
||||||
@showSignupLink={{this.showSignupLink}}
|
<LoginButtons
|
||||||
@createAccount={{this.createAccount}}
|
@externalLogin={{this.externalLoginAction}}
|
||||||
@loggingIn={{this.loggingIn}}
|
@passkeyLogin={{this.passkeyLogin}}
|
||||||
@showSecondFactor={{this.showSecondFactor}}
|
@context="login"
|
||||||
/>
|
/>
|
||||||
{{/unless}}
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{{else}}
|
|
||||||
{{body-class "static-login"}}
|
|
||||||
<section class="container">
|
|
||||||
<div class="contents clearfix body-page">
|
|
||||||
<div class="login-welcome">
|
|
||||||
<PluginOutlet
|
|
||||||
@name="above-login"
|
|
||||||
@outletArgs={{hash model=this.model}}
|
|
||||||
/>
|
|
||||||
<PluginOutlet @name="above-static" />
|
|
||||||
|
|
||||||
<div class="login-content">
|
|
||||||
{{html-safe this.model.html}}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<PluginOutlet @name="below-static" />
|
|
||||||
<PluginOutlet
|
|
||||||
@name="below-login"
|
|
||||||
@outletArgs={{hash model=this.model}}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<div class="body-page-button-container">
|
|
||||||
{{#if this.application.canSignUp}}
|
|
||||||
<DButton
|
|
||||||
@action={{route-action "showCreateAccount"}}
|
|
||||||
@label="sign_up"
|
|
||||||
class="btn-primary sign-up-button"
|
|
||||||
/>
|
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
<DButton
|
{{#if this.site.mobileView}}
|
||||||
@action={{if
|
{{#unless this.hasNoLoginOptions}}
|
||||||
this.shouldTriggerRouteAction
|
<LoginPageCta
|
||||||
(route-action "showLogin")
|
@canLoginLocal={{this.canLoginLocal}}
|
||||||
this.showFullPageLogin
|
@showSecurityKey={{this.showSecurityKey}}
|
||||||
}}
|
@login={{this.triggerLogin}}
|
||||||
@icon="user"
|
@loginButtonLabel={{this.loginButtonLabel}}
|
||||||
@label="log_in"
|
@loginDisabled={{this.loginDisabled}}
|
||||||
class="btn-primary login-button"
|
@showSignupLink={{this.showSignupLink}}
|
||||||
/>
|
@createAccount={{this.createAccount}}
|
||||||
</div>
|
@loggingIn={{this.loggingIn}}
|
||||||
|
@showSecondFactor={{this.showSecondFactor}}
|
||||||
|
/>
|
||||||
|
{{/unless}}
|
||||||
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
|
||||||
|
{{else}}
|
||||||
|
{{body-class "static-login"}}
|
||||||
|
<section class="container">
|
||||||
|
<div class="contents clearfix body-page">
|
||||||
|
<div class="login-welcome">
|
||||||
|
<PluginOutlet
|
||||||
|
@name="above-login"
|
||||||
|
@outletArgs={{hash model=this.model}}
|
||||||
|
/>
|
||||||
|
<PluginOutlet @name="above-static" />
|
||||||
|
|
||||||
|
<div class="login-content">
|
||||||
|
{{html-safe this.model.html}}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<PluginOutlet @name="below-static" />
|
||||||
|
<PluginOutlet
|
||||||
|
@name="below-login"
|
||||||
|
@outletArgs={{hash model=this.model}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div class="body-page-button-container">
|
||||||
|
{{#if this.application.canSignUp}}
|
||||||
|
<DButton
|
||||||
|
@action={{route-action "showCreateAccount"}}
|
||||||
|
@label="sign_up"
|
||||||
|
class="btn-primary sign-up-button"
|
||||||
|
/>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
<DButton
|
||||||
|
@action={{if
|
||||||
|
this.shouldTriggerRouteAction
|
||||||
|
(route-action "showLogin")
|
||||||
|
this.showFullPageLogin
|
||||||
|
}}
|
||||||
|
@icon="user"
|
||||||
|
@label="log_in"
|
||||||
|
class="btn-primary login-button"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
{{/if}}
|
||||||
{{/if}}
|
{{/if}}
|
@ -2,286 +2,294 @@
|
|||||||
{{hide-application-header-buttons "search" "login" "signup" "menu"}}
|
{{hide-application-header-buttons "search" "login" "signup" "menu"}}
|
||||||
{{hide-application-sidebar}}
|
{{hide-application-sidebar}}
|
||||||
{{body-class "signup-page"}}
|
{{body-class "signup-page"}}
|
||||||
<div class="signup-fullpage">
|
|
||||||
<FlashMessage @flash={{this.flash}} @type={{this.flashType}} />
|
|
||||||
|
|
||||||
<div class={{concat-class "signup-body" this.bodyClasses}}>
|
{{#if this.isRedirecting}}
|
||||||
<PluginOutlet
|
{{loading-spinner}}
|
||||||
@name="create-account-before-modal-body"
|
{{else}}
|
||||||
@connectorTagName="div"
|
<div class="signup-fullpage">
|
||||||
/>
|
<FlashMessage @flash={{this.flash}} @type={{this.flashType}} />
|
||||||
|
|
||||||
<div
|
<div class={{concat-class "signup-body" this.bodyClasses}}>
|
||||||
class={{concat-class
|
<PluginOutlet
|
||||||
(if this.site.desktopView "login-left-side")
|
@name="create-account-before-modal-body"
|
||||||
this.authOptions.auth_provider
|
@connectorTagName="div"
|
||||||
}}
|
/>
|
||||||
>
|
|
||||||
<SignupProgressBar @step="signup" />
|
<div
|
||||||
<WelcomeHeader
|
class={{concat-class
|
||||||
id="create-account-title"
|
(if this.site.desktopView "login-left-side")
|
||||||
@header={{i18n "create_account.header_title"}}
|
this.authOptions.auth_provider
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<PluginOutlet
|
<SignupProgressBar @step="signup" />
|
||||||
@name="create-account-header-bottom"
|
<WelcomeHeader
|
||||||
@outletArgs={{hash showLogin=(route-action "showLogin")}}
|
id="create-account-title"
|
||||||
/>
|
@header={{i18n "create_account.header_title"}}
|
||||||
</WelcomeHeader>
|
>
|
||||||
{{#if this.showCreateForm}}
|
|
||||||
<form id="login-form">
|
|
||||||
{{#if this.associateHtml}}
|
|
||||||
<div class="input-group create-account-associate-link">
|
|
||||||
<span>{{html-safe this.associateHtml}}</span>
|
|
||||||
</div>
|
|
||||||
{{/if}}
|
|
||||||
<div class="input-group create-account-email">
|
|
||||||
<Input
|
|
||||||
{{on "focusout" this.checkEmailAvailability}}
|
|
||||||
{{on "focusin" this.scrollInputIntoView}}
|
|
||||||
@type="email"
|
|
||||||
@value={{this.accountEmail}}
|
|
||||||
disabled={{this.emailDisabled}}
|
|
||||||
autofocus="autofocus"
|
|
||||||
aria-describedby="account-email-validation account-email-validation-more-info"
|
|
||||||
aria-invalid={{this.emailValidation.failed}}
|
|
||||||
name="email"
|
|
||||||
id="new-account-email"
|
|
||||||
class={{value-entered this.accountEmail}}
|
|
||||||
/>
|
|
||||||
<label class="alt-placeholder" for="new-account-email">
|
|
||||||
{{i18n "user.email.title"}}
|
|
||||||
</label>
|
|
||||||
{{#if this.showEmailValidation}}
|
|
||||||
<InputTip
|
|
||||||
@validation={{this.emailValidation}}
|
|
||||||
id="account-email-validation"
|
|
||||||
/>
|
|
||||||
{{else}}
|
|
||||||
<span class="more-info" id="account-email-validation-more-info">
|
|
||||||
{{#if this.siteSettings.show_signup_form_email_instructions}}
|
|
||||||
{{i18n "user.email.instructions"}}
|
|
||||||
{{/if}}
|
|
||||||
</span>
|
|
||||||
{{/if}}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="input-group create-account__username">
|
|
||||||
<Input
|
|
||||||
{{on "focusin" this.scrollInputIntoView}}
|
|
||||||
@value={{this.accountUsername}}
|
|
||||||
disabled={{this.usernameDisabled}}
|
|
||||||
maxlength={{this.maxUsernameLength}}
|
|
||||||
aria-describedby="username-validation username-validation-more-info"
|
|
||||||
aria-invalid={{this.usernameValidation.failed}}
|
|
||||||
autocomplete="off"
|
|
||||||
name="username"
|
|
||||||
id="new-account-username"
|
|
||||||
class={{value-entered this.accountUsername}}
|
|
||||||
/>
|
|
||||||
<label class="alt-placeholder" for="new-account-username">
|
|
||||||
{{i18n "user.username.title"}}
|
|
||||||
</label>
|
|
||||||
|
|
||||||
{{#if this.showUsernameInstructions}}
|
|
||||||
<span class="more-info" id="username-validation-more-info">
|
|
||||||
{{i18n "user.username.instructions"}}
|
|
||||||
</span>
|
|
||||||
|
|
||||||
{{else}}
|
|
||||||
<InputTip
|
|
||||||
@validation={{this.usernameValidation}}
|
|
||||||
id="username-validation"
|
|
||||||
/>
|
|
||||||
{{/if}}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{{#if (and this.showFullname this.fullnameRequired)}}
|
|
||||||
<FullnameInput
|
|
||||||
@nameValidation={{this.nameValidation}}
|
|
||||||
@nameTitle={{this.nameTitle}}
|
|
||||||
@accountName={{this.accountName}}
|
|
||||||
@nameDisabled={{this.nameDisabled}}
|
|
||||||
@onFocusIn={{this.scrollInputIntoView}}
|
|
||||||
class="input-group create-account__fullname required"
|
|
||||||
/>
|
|
||||||
{{/if}}
|
|
||||||
|
|
||||||
<PluginOutlet
|
<PluginOutlet
|
||||||
@name="create-account-before-password"
|
@name="create-account-header-bottom"
|
||||||
@outletArgs={{hash
|
@outletArgs={{hash showLogin=(route-action "showLogin")}}
|
||||||
accountName=this.accountName
|
|
||||||
accountUsername=this.accountUsername
|
|
||||||
accountPassword=this.accountPassword
|
|
||||||
userFields=this.userFields
|
|
||||||
authOptions=this.authOptions
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
|
</WelcomeHeader>
|
||||||
<div class="input-group create-account__password">
|
{{#if this.showCreateForm}}
|
||||||
{{#if this.passwordRequired}}
|
<form id="login-form">
|
||||||
<PasswordField
|
{{#if this.associateHtml}}
|
||||||
{{on "focusout" this.togglePasswordValidation}}
|
<div class="input-group create-account-associate-link">
|
||||||
|
<span>{{html-safe this.associateHtml}}</span>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
<div class="input-group create-account-email">
|
||||||
|
<Input
|
||||||
|
{{on "focusout" this.checkEmailAvailability}}
|
||||||
{{on "focusin" this.scrollInputIntoView}}
|
{{on "focusin" this.scrollInputIntoView}}
|
||||||
@value={{this.accountPassword}}
|
@type="email"
|
||||||
@capsLockOn={{this.capsLockOn}}
|
@value={{this.accountEmail}}
|
||||||
type={{if this.maskPassword "password" "text"}}
|
disabled={{this.emailDisabled}}
|
||||||
autocomplete="current-password"
|
autofocus="autofocus"
|
||||||
aria-describedby="password-validation password-validation-more-info"
|
aria-describedby="account-email-validation account-email-validation-more-info"
|
||||||
aria-invalid={{this.passwordValidation.failed}}
|
aria-invalid={{this.emailValidation.failed}}
|
||||||
id="new-account-password"
|
name="email"
|
||||||
class={{value-entered this.accountPassword}}
|
id="new-account-email"
|
||||||
|
class={{value-entered this.accountEmail}}
|
||||||
/>
|
/>
|
||||||
<label class="alt-placeholder" for="new-account-password">
|
<label class="alt-placeholder" for="new-account-email">
|
||||||
{{i18n "user.password.title"}}
|
{{i18n "user.email.title"}}
|
||||||
</label>
|
</label>
|
||||||
<TogglePasswordMask
|
{{#if this.showEmailValidation}}
|
||||||
@maskPassword={{this.maskPassword}}
|
<InputTip
|
||||||
@togglePasswordMask={{this.togglePasswordMask}}
|
@validation={{this.emailValidation}}
|
||||||
/>
|
id="account-email-validation"
|
||||||
<div class="create-account__password-info">
|
/>
|
||||||
<div class="create-account__password-tip-validation">
|
{{else}}
|
||||||
{{#if this.showPasswordValidation}}
|
<span class="more-info" id="account-email-validation-more-info">
|
||||||
<InputTip
|
{{#if this.siteSettings.show_signup_form_email_instructions}}
|
||||||
@validation={{this.passwordValidation}}
|
{{i18n "user.email.instructions"}}
|
||||||
id="password-validation"
|
|
||||||
/>
|
|
||||||
{{else if
|
|
||||||
this.siteSettings.show_signup_form_password_instructions
|
|
||||||
}}
|
|
||||||
<span class="more-info" id="password-validation-more-info">
|
|
||||||
{{this.passwordInstructions}}
|
|
||||||
</span>
|
|
||||||
{{/if}}
|
{{/if}}
|
||||||
<div
|
</span>
|
||||||
class={{concat-class
|
{{/if}}
|
||||||
"caps-lock-warning"
|
</div>
|
||||||
(unless this.capsLockOn "hidden")
|
|
||||||
|
<div class="input-group create-account__username">
|
||||||
|
<Input
|
||||||
|
{{on "focusin" this.scrollInputIntoView}}
|
||||||
|
@value={{this.accountUsername}}
|
||||||
|
disabled={{this.usernameDisabled}}
|
||||||
|
maxlength={{this.maxUsernameLength}}
|
||||||
|
aria-describedby="username-validation username-validation-more-info"
|
||||||
|
aria-invalid={{this.usernameValidation.failed}}
|
||||||
|
autocomplete="off"
|
||||||
|
name="username"
|
||||||
|
id="new-account-username"
|
||||||
|
class={{value-entered this.accountUsername}}
|
||||||
|
/>
|
||||||
|
<label class="alt-placeholder" for="new-account-username">
|
||||||
|
{{i18n "user.username.title"}}
|
||||||
|
</label>
|
||||||
|
|
||||||
|
{{#if this.showUsernameInstructions}}
|
||||||
|
<span class="more-info" id="username-validation-more-info">
|
||||||
|
{{i18n "user.username.instructions"}}
|
||||||
|
</span>
|
||||||
|
|
||||||
|
{{else}}
|
||||||
|
<InputTip
|
||||||
|
@validation={{this.usernameValidation}}
|
||||||
|
id="username-validation"
|
||||||
|
/>
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{#if (and this.showFullname this.fullnameRequired)}}
|
||||||
|
<FullnameInput
|
||||||
|
@nameValidation={{this.nameValidation}}
|
||||||
|
@nameTitle={{this.nameTitle}}
|
||||||
|
@accountName={{this.accountName}}
|
||||||
|
@nameDisabled={{this.nameDisabled}}
|
||||||
|
@onFocusIn={{this.scrollInputIntoView}}
|
||||||
|
class="input-group create-account__fullname required"
|
||||||
|
/>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
<PluginOutlet
|
||||||
|
@name="create-account-before-password"
|
||||||
|
@outletArgs={{hash
|
||||||
|
accountName=this.accountName
|
||||||
|
accountUsername=this.accountUsername
|
||||||
|
accountPassword=this.accountPassword
|
||||||
|
userFields=this.userFields
|
||||||
|
authOptions=this.authOptions
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div class="input-group create-account__password">
|
||||||
|
{{#if this.passwordRequired}}
|
||||||
|
<PasswordField
|
||||||
|
{{on "focusout" this.togglePasswordValidation}}
|
||||||
|
{{on "focusin" this.scrollInputIntoView}}
|
||||||
|
@value={{this.accountPassword}}
|
||||||
|
@capsLockOn={{this.capsLockOn}}
|
||||||
|
type={{if this.maskPassword "password" "text"}}
|
||||||
|
autocomplete="current-password"
|
||||||
|
aria-describedby="password-validation password-validation-more-info"
|
||||||
|
aria-invalid={{this.passwordValidation.failed}}
|
||||||
|
id="new-account-password"
|
||||||
|
class={{value-entered this.accountPassword}}
|
||||||
|
/>
|
||||||
|
<label class="alt-placeholder" for="new-account-password">
|
||||||
|
{{i18n "user.password.title"}}
|
||||||
|
</label>
|
||||||
|
<TogglePasswordMask
|
||||||
|
@maskPassword={{this.maskPassword}}
|
||||||
|
@togglePasswordMask={{this.togglePasswordMask}}
|
||||||
|
/>
|
||||||
|
<div class="create-account__password-info">
|
||||||
|
<div class="create-account__password-tip-validation">
|
||||||
|
{{#if this.showPasswordValidation}}
|
||||||
|
<InputTip
|
||||||
|
@validation={{this.passwordValidation}}
|
||||||
|
id="password-validation"
|
||||||
|
/>
|
||||||
|
{{else if
|
||||||
|
this.siteSettings.show_signup_form_password_instructions
|
||||||
}}
|
}}
|
||||||
>
|
<span
|
||||||
{{d-icon "triangle-exclamation"}}
|
class="more-info"
|
||||||
{{i18n "login.caps_lock_warning"}}
|
id="password-validation-more-info"
|
||||||
|
>
|
||||||
|
{{this.passwordInstructions}}
|
||||||
|
</span>
|
||||||
|
{{/if}}
|
||||||
|
<div
|
||||||
|
class={{concat-class
|
||||||
|
"caps-lock-warning"
|
||||||
|
(unless this.capsLockOn "hidden")
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{{d-icon "triangle-exclamation"}}
|
||||||
|
{{i18n "login.caps_lock_warning"}}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
<div class="password-confirmation">
|
||||||
|
<label for="new-account-password-confirmation">
|
||||||
|
{{i18n "user.password_confirmation.title"}}
|
||||||
|
</label>
|
||||||
|
<HoneypotInput
|
||||||
|
@id="new-account-confirmation"
|
||||||
|
@autocomplete="new-password"
|
||||||
|
@value={{this.accountHoneypot}}
|
||||||
|
/>
|
||||||
|
<Input
|
||||||
|
@value={{this.accountChallenge}}
|
||||||
|
id="new-account-challenge"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{#if this.requireInviteCode}}
|
||||||
|
<div class="input-group create-account__invite-code">
|
||||||
|
<Input
|
||||||
|
{{on "focusin" this.scrollInputIntoView}}
|
||||||
|
@value={{this.inviteCode}}
|
||||||
|
id="inviteCode"
|
||||||
|
class={{value-entered this.inviteCode}}
|
||||||
|
/>
|
||||||
|
<label class="alt-placeholder" for="invite-code">
|
||||||
|
{{i18n "user.invite_code.title"}}
|
||||||
|
</label>
|
||||||
|
<span class="more-info">
|
||||||
|
{{i18n "user.invite_code.instructions"}}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
<div class="password-confirmation">
|
<PluginOutlet
|
||||||
<label for="new-account-password-confirmation">
|
@name="create-account-after-password"
|
||||||
{{i18n "user.password_confirmation.title"}}
|
@outletArgs={{hash
|
||||||
</label>
|
accountName=this.accountName
|
||||||
<HoneypotInput
|
accountUsername=this.accountUsername
|
||||||
@id="new-account-confirmation"
|
accountPassword=this.accountPassword
|
||||||
@autocomplete="new-password"
|
userFields=this.userFields
|
||||||
@value={{this.accountHoneypot}}
|
}}
|
||||||
/>
|
/>
|
||||||
<Input
|
|
||||||
@value={{this.accountChallenge}}
|
|
||||||
id="new-account-challenge"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{{#if this.requireInviteCode}}
|
{{#if (and this.showFullname (not this.fullnameRequired))}}
|
||||||
<div class="input-group create-account__invite-code">
|
<FullnameInput
|
||||||
<Input
|
@nameValidation={{this.nameValidation}}
|
||||||
{{on "focusin" this.scrollInputIntoView}}
|
@nameTitle={{this.nameTitle}}
|
||||||
@value={{this.inviteCode}}
|
@accountName={{this.accountName}}
|
||||||
id="inviteCode"
|
@nameDisabled={{this.nameDisabled}}
|
||||||
class={{value-entered this.inviteCode}}
|
@onFocusIn={{this.scrollInputIntoView}}
|
||||||
|
class="input-group create-account__fullname"
|
||||||
/>
|
/>
|
||||||
<label class="alt-placeholder" for="invite-code">
|
{{/if}}
|
||||||
{{i18n "user.invite_code.title"}}
|
|
||||||
</label>
|
|
||||||
<span class="more-info">
|
|
||||||
{{i18n "user.invite_code.instructions"}}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
{{/if}}
|
|
||||||
|
|
||||||
<PluginOutlet
|
{{#if this.userFields}}
|
||||||
@name="create-account-after-password"
|
<div class="user-fields">
|
||||||
@outletArgs={{hash
|
{{#each this.userFields as |f|}}
|
||||||
accountName=this.accountName
|
<div class="input-group">
|
||||||
accountUsername=this.accountUsername
|
<UserField
|
||||||
accountPassword=this.accountPassword
|
{{on "focusin" this.scrollInputIntoView}}
|
||||||
userFields=this.userFields
|
@field={{f.field}}
|
||||||
}}
|
@value={{f.value}}
|
||||||
/>
|
@validation={{f.validation}}
|
||||||
|
class={{value-entered f.value}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
{{/each}}
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
{{#if (and this.showFullname (not this.fullnameRequired))}}
|
<PluginOutlet
|
||||||
<FullnameInput
|
@name="create-account-after-user-fields"
|
||||||
@nameValidation={{this.nameValidation}}
|
@outletArgs={{hash
|
||||||
@nameTitle={{this.nameTitle}}
|
accountName=this.accountName
|
||||||
@accountName={{this.accountName}}
|
accountUsername=this.accountUsername
|
||||||
@nameDisabled={{this.nameDisabled}}
|
accountPassword=this.accountPassword
|
||||||
@onFocusIn={{this.scrollInputIntoView}}
|
userFields=this.userFields
|
||||||
class="input-group create-account__fullname"
|
}}
|
||||||
|
/>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
{{#if this.site.desktopView}}
|
||||||
|
<SignupPageCta
|
||||||
|
@formSubmitted={{this.formSubmitted}}
|
||||||
|
@hasAuthOptions={{this.hasAuthOptions}}
|
||||||
|
@createAccount={{this.createAccount}}
|
||||||
|
@submitDisabled={{this.submitDisabled}}
|
||||||
|
@disclaimerHtml={{this.disclaimerHtml}}
|
||||||
/>
|
/>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
{{#if this.userFields}}
|
|
||||||
<div class="user-fields">
|
|
||||||
{{#each this.userFields as |f|}}
|
|
||||||
<div class="input-group">
|
|
||||||
<UserField
|
|
||||||
{{on "focusin" this.scrollInputIntoView}}
|
|
||||||
@field={{f.field}}
|
|
||||||
@value={{f.value}}
|
|
||||||
@validation={{f.validation}}
|
|
||||||
class={{value-entered f.value}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
{{/each}}
|
|
||||||
</div>
|
|
||||||
{{/if}}
|
|
||||||
|
|
||||||
<PluginOutlet
|
|
||||||
@name="create-account-after-user-fields"
|
|
||||||
@outletArgs={{hash
|
|
||||||
accountName=this.accountName
|
|
||||||
accountUsername=this.accountUsername
|
|
||||||
accountPassword=this.accountPassword
|
|
||||||
userFields=this.userFields
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
{{#if this.site.desktopView}}
|
|
||||||
<SignupPageCta
|
|
||||||
@formSubmitted={{this.formSubmitted}}
|
|
||||||
@hasAuthOptions={{this.hasAuthOptions}}
|
|
||||||
@createAccount={{this.createAccount}}
|
|
||||||
@submitDisabled={{this.submitDisabled}}
|
|
||||||
@disclaimerHtml={{this.disclaimerHtml}}
|
|
||||||
/>
|
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if this.skipConfirmation}}
|
||||||
|
{{loading-spinner size="large"}}
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{#if this.hasAtLeastOneLoginButton}}
|
||||||
|
{{#if this.site.mobileView}}
|
||||||
|
<div class="login-or-separator"><span>
|
||||||
|
{{i18n "login.or"}}</span></div>{{/if}}
|
||||||
|
<div class="login-right-side">
|
||||||
|
<LoginButtons
|
||||||
|
@externalLogin={{this.externalLogin}}
|
||||||
|
@context="create-account"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
{{#if this.skipConfirmation}}
|
{{#if (and this.showCreateForm this.site.mobileView)}}
|
||||||
{{loading-spinner size="large"}}
|
<SignupPageCta
|
||||||
|
@formSubmitted={{this.formSubmitted}}
|
||||||
|
@hasAuthOptions={{this.hasAuthOptions}}
|
||||||
|
@createAccount={{this.createAccount}}
|
||||||
|
@submitDisabled={{this.submitDisabled}}
|
||||||
|
@disclaimerHtml={{this.disclaimerHtml}}
|
||||||
|
/>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{#if this.hasAtLeastOneLoginButton}}
|
|
||||||
{{#if this.site.mobileView}}
|
|
||||||
<div class="login-or-separator"><span>
|
|
||||||
{{i18n "login.or"}}</span></div>{{/if}}
|
|
||||||
<div class="login-right-side">
|
|
||||||
<LoginButtons
|
|
||||||
@externalLogin={{this.externalLogin}}
|
|
||||||
@context="create-account"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
{{/if}}
|
|
||||||
|
|
||||||
{{#if (and this.showCreateForm this.site.mobileView)}}
|
|
||||||
<SignupPageCta
|
|
||||||
@formSubmitted={{this.formSubmitted}}
|
|
||||||
@hasAuthOptions={{this.hasAuthOptions}}
|
|
||||||
@createAccount={{this.createAccount}}
|
|
||||||
@submitDisabled={{this.submitDisabled}}
|
|
||||||
@disclaimerHtml={{this.disclaimerHtml}}
|
|
||||||
/>
|
|
||||||
{{/if}}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
{{/if}}
|
@ -232,6 +232,34 @@ shared_examples "social authentication scenarios" do |signup_page_object, login_
|
|||||||
expect(page).to have_css(".header-dropdown-toggle.current-user")
|
expect(page).to have_css(".header-dropdown-toggle.current-user")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context "when there is only one external login method enabled" do
|
||||||
|
before do
|
||||||
|
SiteSetting.enable_google_oauth2_logins = true
|
||||||
|
SiteSetting.enable_local_logins = false
|
||||||
|
end
|
||||||
|
after { reset_omniauth_config(:google_oauth2) }
|
||||||
|
|
||||||
|
it "automatically redirects to the external auth provider" do
|
||||||
|
mock_google_auth
|
||||||
|
visit("/login")
|
||||||
|
|
||||||
|
expect(signup_form).to be_open
|
||||||
|
expect(signup_form).to have_no_password_input
|
||||||
|
expect(signup_form).to have_valid_username
|
||||||
|
expect(signup_form).to have_valid_email
|
||||||
|
signup_form.click_create_account
|
||||||
|
expect(page).to have_css(".header-dropdown-toggle.current-user")
|
||||||
|
end
|
||||||
|
|
||||||
|
it "automatically redirects to the external auth provider when skipping the signup form" do
|
||||||
|
SiteSetting.auth_skip_create_confirm = true
|
||||||
|
mock_google_auth
|
||||||
|
visit("/login")
|
||||||
|
|
||||||
|
expect(page).to have_css(".header-dropdown-toggle.current-user")
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context "when user exists" do
|
context "when user exists" do
|
||||||
|
Reference in New Issue
Block a user