mirror of
https://github.com/discourse/discourse.git
synced 2025-02-24 11:33:26 +08:00
FIX: Automatic auth flow with full page login/signup V3 (#31072)
This adds back the fixes from https://github.com/discourse/discourse/pull/30928 that were reverted by https://github.com/discourse/discourse/pull/30960.
This commit is contained in:
parent
891d8fe574
commit
42447770bf
@ -119,7 +119,8 @@ export default class LoginPageController extends Controller {
|
||||
get shouldTriggerRouteAction() {
|
||||
return (
|
||||
!this.siteSettings.full_page_login ||
|
||||
this.siteSettings.enable_discourse_connect
|
||||
this.siteSettings.enable_discourse_connect ||
|
||||
this.singleExternalLogin
|
||||
);
|
||||
}
|
||||
|
||||
@ -220,7 +221,10 @@ export default class LoginPageController extends Controller {
|
||||
const returnPath = encodeURIComponent(window.location.pathname);
|
||||
window.location = getURL("/session/sso?return_path=" + returnPath);
|
||||
} else {
|
||||
if (this.isOnlyOneExternalLoginMethod) {
|
||||
if (
|
||||
this.isOnlyOneExternalLoginMethod &&
|
||||
this.siteSettings.auth_immediately
|
||||
) {
|
||||
// we will automatically redirect to the external auth service
|
||||
this.login.externalLogin(this.externalLoginMethods[0], {
|
||||
signup: true,
|
||||
|
@ -17,7 +17,6 @@ import DiscourseURL from "discourse/lib/url";
|
||||
import { postRNWebviewMessage } from "discourse/lib/utilities";
|
||||
import Category from "discourse/models/category";
|
||||
import Composer from "discourse/models/composer";
|
||||
import { findAll } from "discourse/models/login-method";
|
||||
import DiscourseRoute from "discourse/routes/discourse";
|
||||
import { i18n } from "discourse-i18n";
|
||||
|
||||
@ -44,17 +43,6 @@ export default class ApplicationRoute extends DiscourseRoute {
|
||||
@setting("title") siteTitle;
|
||||
@setting("short_site_description") shortSiteDescription;
|
||||
|
||||
get isOnlyOneExternalLoginMethod() {
|
||||
return (
|
||||
!this.siteSettings.enable_local_logins &&
|
||||
this.externalLoginMethods.length === 1
|
||||
);
|
||||
}
|
||||
|
||||
get externalLoginMethods() {
|
||||
return findAll();
|
||||
}
|
||||
|
||||
@action
|
||||
loading(transition) {
|
||||
this.loadingSlider.transitionStarted();
|
||||
@ -295,8 +283,8 @@ export default class ApplicationRoute extends DiscourseRoute {
|
||||
: encodeURIComponent(window.location.pathname);
|
||||
window.location = getURL("/session/sso?return_path=" + returnPath);
|
||||
} else {
|
||||
if (this.isOnlyOneExternalLoginMethod) {
|
||||
this.login.externalLogin(this.externalLoginMethods[0]);
|
||||
if (this.login.isOnlyOneExternalLoginMethod) {
|
||||
this.login.singleExternalLogin();
|
||||
} else if (this.siteSettings.full_page_login) {
|
||||
this.router.transitionTo("login").then((login) => {
|
||||
login.controller.set("canSignUp", this.controller.canSignUp);
|
||||
@ -321,11 +309,9 @@ export default class ApplicationRoute extends DiscourseRoute {
|
||||
const returnPath = encodeURIComponent(window.location.pathname);
|
||||
window.location = getURL("/session/sso?return_path=" + returnPath);
|
||||
} else {
|
||||
if (this.isOnlyOneExternalLoginMethod) {
|
||||
if (this.login.isOnlyOneExternalLoginMethod) {
|
||||
// we will automatically redirect to the external auth service
|
||||
this.login.externalLogin(this.externalLoginMethods[0], {
|
||||
signup: true,
|
||||
});
|
||||
this.login.singleExternalLogin({ signup: true });
|
||||
} else if (this.siteSettings.full_page_login) {
|
||||
this.router.transitionTo("signup").then((signup) => {
|
||||
Object.keys(createAccountProps || {}).forEach((key) => {
|
||||
|
@ -7,12 +7,26 @@ import DiscourseRoute from "discourse/routes/discourse";
|
||||
export default class LoginRoute extends DiscourseRoute {
|
||||
@service siteSettings;
|
||||
@service router;
|
||||
@service login;
|
||||
|
||||
beforeModel() {
|
||||
if (
|
||||
!this.siteSettings.login_required &&
|
||||
(!this.siteSettings.full_page_login ||
|
||||
this.siteSettings.enable_discourse_connect)
|
||||
if (this.siteSettings.login_required) {
|
||||
if (
|
||||
this.login.isOnlyOneExternalLoginMethod &&
|
||||
this.siteSettings.auth_immediately &&
|
||||
!document.getElementById("data-authentication")?.dataset
|
||||
.authenticationData
|
||||
) {
|
||||
this.login.singleExternalLogin();
|
||||
}
|
||||
} else if (
|
||||
this.login.isOnlyOneExternalLoginMethod &&
|
||||
this.siteSettings.full_page_login
|
||||
) {
|
||||
this.login.singleExternalLogin();
|
||||
} else if (
|
||||
!this.siteSettings.full_page_login ||
|
||||
this.siteSettings.enable_discourse_connect
|
||||
) {
|
||||
this.router
|
||||
.replaceWith(`/${defaultHomepage()}`)
|
||||
@ -38,5 +52,13 @@ export default class LoginRoute extends DiscourseRoute {
|
||||
if (this.siteSettings.login_required) {
|
||||
controller.set("showLogin", false);
|
||||
}
|
||||
|
||||
if (this.login.isOnlyOneExternalLoginMethod) {
|
||||
if (this.siteSettings.auth_immediately) {
|
||||
controller.set("isRedirectingToExternalAuth", true);
|
||||
} else {
|
||||
controller.set("singleExternalLogin", this.login.singleExternalLogin);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,11 +4,30 @@ import { service } from "@ember/service";
|
||||
import DiscourseRoute from "discourse/routes/discourse";
|
||||
|
||||
export default class SignupRoute extends DiscourseRoute {
|
||||
@service router;
|
||||
@service siteSettings;
|
||||
@service router;
|
||||
@service login;
|
||||
|
||||
authComplete = false;
|
||||
|
||||
beforeModel() {
|
||||
this.showCreateAccount();
|
||||
this.authComplete = document.getElementById(
|
||||
"data-authentication"
|
||||
)?.dataset.authenticationData;
|
||||
|
||||
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("isRedirectingToExternalAuth", true);
|
||||
}
|
||||
}
|
||||
|
||||
@action
|
||||
|
@ -1,9 +1,12 @@
|
||||
import { action } from "@ember/object";
|
||||
import Service from "@ember/service";
|
||||
import Service, { service } from "@ember/service";
|
||||
import { disableImplicitInjections } from "discourse/lib/implicit-injections";
|
||||
import { findAll } from "discourse/models/login-method";
|
||||
|
||||
@disableImplicitInjections
|
||||
export default class LoginService extends Service {
|
||||
@service siteSettings;
|
||||
|
||||
@action
|
||||
async externalLogin(
|
||||
loginMethod,
|
||||
@ -16,4 +19,20 @@ export default class LoginService extends Service {
|
||||
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,187 @@
|
||||
{{#if
|
||||
(and
|
||||
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}} />
|
||||
{{hide-application-header-buttons "search" "login" "signup" "menu"}}
|
||||
{{hide-application-sidebar}}
|
||||
{{body-class "login-page"}}
|
||||
|
||||
<div class={{concat-class "login-body" this.bodyClasses}}>
|
||||
<PluginOutlet @name="login-before-modal-body" @connectorTagName="div" />
|
||||
{{#if this.isRedirectingToExternalAuth}}
|
||||
{{! Hide the login form if the site has only one external }}
|
||||
{{! authentication method and is being automatically redirected to it }}
|
||||
{{loading-spinner}}
|
||||
{{else}}
|
||||
{{#if
|
||||
(and
|
||||
this.siteSettings.full_page_login
|
||||
(or this.showLogin (not this.siteSettings.login_required))
|
||||
)
|
||||
}}
|
||||
{{! Show the full page login form }}
|
||||
<div class="login-fullpage">
|
||||
<FlashMessage @flash={{this.flash}} @type={{this.flashType}} />
|
||||
|
||||
{{#if this.hasNoLoginOptions}}
|
||||
<div class={{if this.site.desktopView "login-left-side"}}>
|
||||
<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}}
|
||||
<div class={{concat-class "login-body" this.bodyClasses}}>
|
||||
<PluginOutlet @name="login-before-modal-body" @connectorTagName="div" />
|
||||
|
||||
{{#if this.canLoginLocal}}
|
||||
{{#if this.hasNoLoginOptions}}
|
||||
<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>
|
||||
{{/if}}
|
||||
|
||||
{{#if (and this.showLoginButtons this.site.desktopView)}}
|
||||
{{#unless this.canLoginLocal}}
|
||||
<div class="login-left-side">
|
||||
<WelcomeHeader @header={{i18n "login.header_title"}} />
|
||||
<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>
|
||||
{{/unless}}
|
||||
{{#if this.hasAtLeastOneLoginButton}}
|
||||
<div class="login-right-side">
|
||||
</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}}
|
||||
<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>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
|
||||
{{#if this.site.mobileView}}
|
||||
{{#unless this.hasNoLoginOptions}}
|
||||
<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}}
|
||||
/>
|
||||
{{/unless}}
|
||||
{{/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 (and this.showLoginButtons this.site.desktopView)}}
|
||||
{{#unless this.canLoginLocal}}
|
||||
<div class="login-left-side">
|
||||
<WelcomeHeader @header={{i18n "login.header_title"}} />
|
||||
</div>
|
||||
{{/unless}}
|
||||
{{#if this.hasAtLeastOneLoginButton}}
|
||||
<div class="login-right-side">
|
||||
<LoginButtons
|
||||
@externalLogin={{this.externalLoginAction}}
|
||||
@passkeyLogin={{this.passkeyLogin}}
|
||||
@context="login"
|
||||
/>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
|
||||
<DButton
|
||||
@action={{if
|
||||
this.shouldTriggerRouteAction
|
||||
(route-action "showLogin")
|
||||
this.showFullPageLogin
|
||||
}}
|
||||
@icon="user"
|
||||
@label="log_in"
|
||||
class="btn-primary login-button"
|
||||
/>
|
||||
</div>
|
||||
{{#if this.site.mobileView}}
|
||||
{{#unless this.hasNoLoginOptions}}
|
||||
<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}}
|
||||
/>
|
||||
{{/unless}}
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{{else}}
|
||||
{{! Show the login-required splash screen }}
|
||||
{{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}}
|
@ -2,288 +2,298 @@
|
||||
{{hide-application-header-buttons "search" "login" "signup" "menu"}}
|
||||
{{hide-application-sidebar}}
|
||||
{{body-class "signup-page"}}
|
||||
<div class="signup-fullpage">
|
||||
<FlashMessage @flash={{this.flash}} @type={{this.flashType}} />
|
||||
|
||||
<div class={{concat-class "signup-body" this.bodyClasses}}>
|
||||
<PluginOutlet
|
||||
@name="create-account-before-modal-body"
|
||||
@connectorTagName="div"
|
||||
/>
|
||||
{{#if this.isRedirectingToExternalAuth}}
|
||||
{{! Hide the signup form if the site has only one external }}
|
||||
{{! authentication method and is being automatically redirected to it }}
|
||||
{{loading-spinner}}
|
||||
{{else}}
|
||||
<div class="signup-fullpage">
|
||||
<FlashMessage @flash={{this.flash}} @type={{this.flashType}} />
|
||||
|
||||
<div
|
||||
class={{concat-class
|
||||
(if this.site.desktopView "login-left-side")
|
||||
this.authOptions.auth_provider
|
||||
}}
|
||||
>
|
||||
<SignupProgressBar @step="signup" />
|
||||
<WelcomeHeader
|
||||
id="create-account-title"
|
||||
@header={{i18n "create_account.header_title"}}
|
||||
<div class={{concat-class "signup-body" this.bodyClasses}}>
|
||||
<PluginOutlet
|
||||
@name="create-account-before-modal-body"
|
||||
@connectorTagName="div"
|
||||
/>
|
||||
|
||||
<div
|
||||
class={{concat-class
|
||||
(if this.site.desktopView "login-left-side")
|
||||
this.authOptions.auth_provider
|
||||
}}
|
||||
>
|
||||
<PluginOutlet
|
||||
@name="create-account-header-bottom"
|
||||
@outletArgs={{hash showLogin=(route-action "showLogin")}}
|
||||
/>
|
||||
</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}}
|
||||
{{on "input" this.setAccountUsername}}
|
||||
type="text"
|
||||
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}}
|
||||
|
||||
<SignupProgressBar @step="signup" />
|
||||
<WelcomeHeader
|
||||
id="create-account-title"
|
||||
@header={{i18n "create_account.header_title"}}
|
||||
>
|
||||
<PluginOutlet
|
||||
@name="create-account-before-password"
|
||||
@outletArgs={{hash
|
||||
accountName=this.accountName
|
||||
accountUsername=this.accountUsername
|
||||
accountPassword=this.accountPassword
|
||||
userFields=this.userFields
|
||||
authOptions=this.authOptions
|
||||
}}
|
||||
@name="create-account-header-bottom"
|
||||
@outletArgs={{hash showLogin=(route-action "showLogin")}}
|
||||
/>
|
||||
|
||||
<div class="input-group create-account__password">
|
||||
{{#if this.passwordRequired}}
|
||||
<PasswordField
|
||||
{{on "focusout" this.togglePasswordValidation}}
|
||||
</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}}
|
||||
@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}}
|
||||
@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-password">
|
||||
{{i18n "user.password.title"}}
|
||||
<label class="alt-placeholder" for="new-account-email">
|
||||
{{i18n "user.email.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 class="more-info" id="password-validation-more-info">
|
||||
{{this.passwordInstructions}}
|
||||
</span>
|
||||
{{#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}}
|
||||
<div
|
||||
class={{concat-class
|
||||
"caps-lock-warning"
|
||||
(unless this.capsLockOn "hidden")
|
||||
</span>
|
||||
{{/if}}
|
||||
</div>
|
||||
|
||||
<div class="input-group create-account__username">
|
||||
<input
|
||||
{{on "focusin" this.scrollInputIntoView}}
|
||||
{{on "input" this.setAccountUsername}}
|
||||
type="text"
|
||||
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
|
||||
}}
|
||||
>
|
||||
{{d-icon "triangle-exclamation"}}
|
||||
{{i18n "login.caps_lock_warning"}}
|
||||
<span
|
||||
class="more-info"
|
||||
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>
|
||||
{{/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>
|
||||
{{/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>
|
||||
<PluginOutlet
|
||||
@name="create-account-after-password"
|
||||
@outletArgs={{hash
|
||||
accountName=this.accountName
|
||||
accountUsername=this.accountUsername
|
||||
accountPassword=this.accountPassword
|
||||
userFields=this.userFields
|
||||
}}
|
||||
/>
|
||||
|
||||
{{#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}}
|
||||
{{#if (and this.showFullname (not this.fullnameRequired))}}
|
||||
<FullnameInput
|
||||
@nameValidation={{this.nameValidation}}
|
||||
@nameTitle={{this.nameTitle}}
|
||||
@accountName={{this.accountName}}
|
||||
@nameDisabled={{this.nameDisabled}}
|
||||
@onFocusIn={{this.scrollInputIntoView}}
|
||||
class="input-group create-account__fullname"
|
||||
/>
|
||||
<label class="alt-placeholder" for="invite-code">
|
||||
{{i18n "user.invite_code.title"}}
|
||||
</label>
|
||||
<span class="more-info">
|
||||
{{i18n "user.invite_code.instructions"}}
|
||||
</span>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
|
||||
<PluginOutlet
|
||||
@name="create-account-after-password"
|
||||
@outletArgs={{hash
|
||||
accountName=this.accountName
|
||||
accountUsername=this.accountUsername
|
||||
accountPassword=this.accountPassword
|
||||
userFields=this.userFields
|
||||
}}
|
||||
/>
|
||||
{{#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}}
|
||||
|
||||
{{#if (and this.showFullname (not this.fullnameRequired))}}
|
||||
<FullnameInput
|
||||
@nameValidation={{this.nameValidation}}
|
||||
@nameTitle={{this.nameTitle}}
|
||||
@accountName={{this.accountName}}
|
||||
@nameDisabled={{this.nameDisabled}}
|
||||
@onFocusIn={{this.scrollInputIntoView}}
|
||||
class="input-group create-account__fullname"
|
||||
<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 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 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 this.skipConfirmation}}
|
||||
{{loading-spinner size="large"}}
|
||||
{{#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>
|
||||
|
||||
{{#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>
|
||||
{{/if}}
|
@ -3,7 +3,7 @@ import { test } from "qunit";
|
||||
import { acceptance } from "discourse/tests/helpers/qunit-helpers";
|
||||
|
||||
acceptance("Login Required", function (needs) {
|
||||
needs.settings({ login_required: true });
|
||||
needs.settings({ login_required: true, full_page_login: false });
|
||||
|
||||
test("redirect", async function (assert) {
|
||||
await visit("/latest");
|
||||
@ -13,17 +13,33 @@ acceptance("Login Required", function (needs) {
|
||||
"it redirects them to login"
|
||||
);
|
||||
|
||||
await click("#site-logo");
|
||||
assert.strictEqual(
|
||||
currentRouteName(),
|
||||
"login",
|
||||
"clicking the logo keeps them on login"
|
||||
);
|
||||
|
||||
await click("header .login-button");
|
||||
assert.dom(".login-modal").exists("they can still access the login modal");
|
||||
await click(".login-button");
|
||||
assert.dom(".login-modal").exists("login modal is shown");
|
||||
|
||||
await click(".d-modal__header .modal-close");
|
||||
assert.dom(".login-modal").doesNotExist("closes the login modal");
|
||||
});
|
||||
});
|
||||
|
||||
acceptance("Login Required - Full page login", function (needs) {
|
||||
needs.settings({ login_required: true, full_page_login: true });
|
||||
|
||||
test("page", async function (assert) {
|
||||
await visit("/");
|
||||
assert.strictEqual(
|
||||
currentRouteName(),
|
||||
"login",
|
||||
"it redirects them to login"
|
||||
);
|
||||
|
||||
await click(".login-button");
|
||||
assert.dom(".login-left-side").exists("login form is shown");
|
||||
assert
|
||||
.dom(".login-welcome")
|
||||
.doesNotExist("login welcome is no longer shown");
|
||||
|
||||
await click(".logo-big");
|
||||
assert.dom(".login-left-side").doesNotExist("closes the login modal");
|
||||
assert.dom(".login-welcome").exists("login welcome is shown");
|
||||
});
|
||||
});
|
||||
|
@ -600,6 +600,7 @@ login:
|
||||
client: true
|
||||
auth_immediately:
|
||||
default: true
|
||||
client: true
|
||||
auth_overrides_email:
|
||||
default: false
|
||||
validator: "SsoOverridesEmailValidator"
|
||||
|
@ -232,6 +232,143 @@ shared_examples "social authentication scenarios" do |signup_page_object, login_
|
||||
expect(page).to have_css(".header-dropdown-toggle.current-user")
|
||||
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) }
|
||||
|
||||
context "when login is required" do
|
||||
before { SiteSetting.login_required = true }
|
||||
|
||||
it "automatically redirects when auth_immediately is enabled" do
|
||||
SiteSetting.auth_immediately = true
|
||||
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
|
||||
|
||||
visit("/signup")
|
||||
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
|
||||
|
||||
visit("/")
|
||||
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 "shows the login-required page when auth_immediately is disabled" do
|
||||
SiteSetting.auth_immediately = false
|
||||
mock_google_auth
|
||||
|
||||
visit("/login")
|
||||
expect(page).to have_css(".login-welcome")
|
||||
expect(page).to have_css(".site-logo")
|
||||
|
||||
visit("/")
|
||||
expect(page).to have_css(".login-welcome")
|
||||
expect(page).to have_css(".site-logo")
|
||||
|
||||
find(".login-welcome .login-button").click
|
||||
expect(signup_form).to be_open
|
||||
|
||||
visit("/")
|
||||
find(".login-welcome .sign-up-button").click
|
||||
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 when going to /signup" do
|
||||
SiteSetting.auth_immediately = false
|
||||
mock_google_auth
|
||||
|
||||
visit("/signup")
|
||||
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 when skipping the signup form" do
|
||||
SiteSetting.auth_skip_create_confirm = true
|
||||
SiteSetting.auth_immediately = true
|
||||
mock_google_auth
|
||||
|
||||
visit("/login")
|
||||
expect(page).to have_css(".header-dropdown-toggle.current-user")
|
||||
end
|
||||
|
||||
it "works with existing users when auth_immediately is enabled" do
|
||||
SiteSetting.auth_immediately = false
|
||||
SiteSetting.login_required = true
|
||||
mock_google_auth
|
||||
|
||||
visit("/signup")
|
||||
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
|
||||
|
||||
find(".header-dropdown-toggle.current-user").click
|
||||
find("#user-menu-button-profile").click
|
||||
find("#quick-access-profile .logout").click
|
||||
visit("/")
|
||||
find(".login-welcome .login-button").click
|
||||
expect(page).to have_css(".header-dropdown-toggle.current-user")
|
||||
end
|
||||
end
|
||||
|
||||
it "automatically redirects when using the login button" do
|
||||
SiteSetting.auth_immediately = false
|
||||
mock_google_auth
|
||||
|
||||
visit("/")
|
||||
find(".header-buttons .login-button").click
|
||||
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 when using the routes" do
|
||||
SiteSetting.auth_immediately = false
|
||||
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
|
||||
|
||||
visit("/signup")
|
||||
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
|
||||
end
|
||||
end
|
||||
|
||||
context "when user exists" do
|
||||
|
Loading…
x
Reference in New Issue
Block a user