mirror of
				https://github.com/lingble/chatwoot.git
				synced 2025-10-31 02:57:57 +00:00 
			
		
		
		
	Chore: Making Account Signup Optional (#563)
Introduce new environment variable that lets you control account signups ENABLE_ACCOUNT_SIGNUP :( true | false | api_only ) Fixes: #406 Co-authored-by: Pranav Raj S <pranavrajs@gmail.com>
This commit is contained in:
		| @@ -2,6 +2,12 @@ SECRET_KEY_BASE= | ||||
| # Force all access to the app over SSL, default is set to false | ||||
| FORCE_SSL= | ||||
|  | ||||
| # This lets you control new sign ups on your chatwoot installation | ||||
| # true : default option, allows sign ups | ||||
| # false : disables all the end points related to sign ups | ||||
| # api_only: disables the UI for signup, but you can create sign ups via the account apis | ||||
| ENABLE_ACCOUNT_SIGNUP=  | ||||
|  | ||||
| #redis config | ||||
| REDIS_URL=redis://redis:6379 | ||||
| # If you are using docker-compose, set this variable's value to be any string, | ||||
|   | ||||
| @@ -4,6 +4,7 @@ class Api::V1::AccountsController < Api::BaseController | ||||
|   skip_before_action :verify_authenticity_token, only: [:create] | ||||
|   skip_before_action :authenticate_user!, :set_current_user, :check_subscription, :handle_with_exception, | ||||
|                      only: [:create], raise: false | ||||
|   before_action :check_signup_enabled | ||||
|  | ||||
|   rescue_from CustomExceptions::Account::InvalidEmail, | ||||
|               CustomExceptions::Account::UserExists, | ||||
| @@ -30,4 +31,8 @@ class Api::V1::AccountsController < Api::BaseController | ||||
|   def account_params | ||||
|     params.permit(:account_name, :email) | ||||
|   end | ||||
|  | ||||
|   def check_signup_enabled | ||||
|     raise ActionController::RoutingError, 'Not Found' if ENV.fetch('ENABLE_ACCOUNT_SIGNUP', true) == 'false' | ||||
|   end | ||||
| end | ||||
|   | ||||
| @@ -36,6 +36,7 @@ export default { | ||||
|           path: 'signup', | ||||
|           name: 'auth_signup', | ||||
|           component: Signup, | ||||
|           meta: { requireSignupEnabled: true }, | ||||
|         }, | ||||
|         { | ||||
|           path: 'reset/password', | ||||
|   | ||||
| @@ -97,6 +97,14 @@ export const validateAuthenticateRoutePermission = (to, from, next) => { | ||||
| }; | ||||
|  | ||||
| const validateRouteAccess = (to, from, next) => { | ||||
|   if ( | ||||
|     window.chatwootConfig.signupEnabled !== 'true' && | ||||
|     to.meta && | ||||
|     to.meta.requireSignupEnabled | ||||
|   ) { | ||||
|     next(frontendURL('dashboard')); | ||||
|   } | ||||
|  | ||||
|   if (authIgnoreRoutes.includes(to.name)) { | ||||
|     return next(); | ||||
|   } | ||||
|   | ||||
| @@ -1,24 +1,44 @@ | ||||
| <template> | ||||
|   <div class="medium-12 column login"> | ||||
|     <div class="text-center medium-12 login__hero align-self-top"> | ||||
|       <img src="~dashboard/assets/images/woot-logo.svg" alt="Woot-logo" class="hero__logo" /> | ||||
|       <h2 class="hero__title">{{$t('LOGIN.TITLE')}}</h2> | ||||
|       <img | ||||
|         src="~dashboard/assets/images/woot-logo.svg" | ||||
|         alt="Woot-logo" | ||||
|         class="hero__logo" | ||||
|       /> | ||||
|       <h2 class="hero__title"> | ||||
|         {{ $t('LOGIN.TITLE') }} | ||||
|       </h2> | ||||
|     </div> | ||||
|     <div class="row align-center"> | ||||
|       <div class="small-12 medium-4 column"> | ||||
|         <form class="login-box column align-self-top" v-on:submit.prevent="login()"> | ||||
|         <form class="login-box column align-self-top" @submit.prevent="login()"> | ||||
|           <div class="column log-in-form"> | ||||
|             <!-- <h4 class="text-center">{{$t('LOGIN.TITLE')}}</h4> --> | ||||
|             <label :class="{ 'error': $v.credentials.email.$error }"> | ||||
|               {{$t('LOGIN.EMAIL.LABEL')}} | ||||
|               <input type="text" v-bind:placeholder="$t('LOGIN.EMAIL.PLACEHOLDER')" v-model.trim="credentials.email" @input="$v.credentials.email.$touch"> | ||||
|             <label :class="{ error: $v.credentials.email.$error }"> | ||||
|               {{ $t('LOGIN.EMAIL.LABEL') }} | ||||
|               <input | ||||
|                 v-model.trim="credentials.email" | ||||
|                 type="text" | ||||
|                 :placeholder="$t('LOGIN.EMAIL.PLACEHOLDER')" | ||||
|                 @input="$v.credentials.email.$touch" | ||||
|               /> | ||||
|             </label> | ||||
|             <label :class="{ 'error': $v.credentials.password.$error }"> | ||||
|               {{$t('LOGIN.PASSWORD.LABEL')}} | ||||
|               <input type="password" v-bind:placeholder="$t('LOGIN.PASSWORD.PLACEHOLDER')" v-model.trim="credentials.password" @input="$v.credentials.password.$touch"> | ||||
|             <label :class="{ error: $v.credentials.password.$error }"> | ||||
|               {{ $t('LOGIN.PASSWORD.LABEL') }} | ||||
|               <input | ||||
|                 v-model.trim="credentials.password" | ||||
|                 type="password" | ||||
|                 :placeholder="$t('LOGIN.PASSWORD.PLACEHOLDER')" | ||||
|                 @input="$v.credentials.password.$touch" | ||||
|               /> | ||||
|             </label> | ||||
|             <woot-submit-button | ||||
|               :disabled="$v.credentials.email.$invalid || $v.credentials.password.$invalid || loginApi.showLoading" | ||||
|               :disabled=" | ||||
|                 $v.credentials.email.$invalid || | ||||
|                   $v.credentials.password.$invalid || | ||||
|                   loginApi.showLoading | ||||
|               " | ||||
|               :button-text="$t('LOGIN.SUBMIT')" | ||||
|               :loading="loginApi.showLoading" | ||||
|               button-class="large expanded" | ||||
| @@ -30,10 +50,10 @@ | ||||
|         <div class="column text-center sigin__footer"> | ||||
|           <p> | ||||
|             <router-link to="auth/reset/password"> | ||||
|               {{$t('LOGIN.FORGOT_PASSWORD')}} | ||||
|               {{ $t('LOGIN.FORGOT_PASSWORD') }} | ||||
|             </router-link> | ||||
|           </p> | ||||
|           <p> | ||||
|           <p v-if="showSignupLink()"> | ||||
|             <router-link to="auth/signup"> | ||||
|               {{ $t('LOGIN.CREATE_NEW_ACCOUNT') }} | ||||
|             </router-link> | ||||
| @@ -89,6 +109,9 @@ export default { | ||||
|       this.loginApi.message = message; | ||||
|       bus.$emit('newToastMessage', this.loginApi.message); | ||||
|     }, | ||||
|     showSignupLink() { | ||||
|       return window.chatwootConfig.signupEnabled === 'true'; | ||||
|     }, | ||||
|     login() { | ||||
|       this.loginApi.showLoading = true; | ||||
|       const credentials = { | ||||
| @@ -100,7 +123,7 @@ export default { | ||||
|         .then(() => { | ||||
|           this.showAlert(this.$t('LOGIN.API.SUCCESS_MESSAGE')); | ||||
|         }) | ||||
|         .catch((response) => { | ||||
|         .catch(response => { | ||||
|           if (response && response.status === 401) { | ||||
|             this.showAlert(this.$t('LOGIN.API.UNAUTH')); | ||||
|             return; | ||||
|   | ||||
| @@ -31,8 +31,9 @@ | ||||
|     <%= yield %> | ||||
|     <script> | ||||
|       window.chatwootConfig = { | ||||
|         fbAppId: '<%= ENV['FB_APP_ID'] %>', | ||||
|         billingEnabled: '<%= ENV['BILLING_ENABLED'] %>' | ||||
|         fbAppId: '<%= ENV.fetch('FB_APP_ID', nil) %>', | ||||
|         billingEnabled: <%= ActiveModel::Type::Boolean.new.cast(ENV.fetch('BILLING_ENABLED', false)) %>, | ||||
|         signupEnabled: '<%= ENV.fetch('ENABLE_ACCOUNT_SIGNUP', true) %>' | ||||
|       } | ||||
|     </script> | ||||
|   </body> | ||||
|   | ||||
| @@ -9,6 +9,7 @@ RSpec.describe 'Accounts API', type: :request do | ||||
|  | ||||
|       before do | ||||
|         allow(AccountBuilder).to receive(:new).and_return(account_builder) | ||||
|         ENV['ENABLE_ACCOUNT_SIGNUP'] = nil | ||||
|       end | ||||
|  | ||||
|       it 'calls account builder' do | ||||
| @@ -40,5 +41,37 @@ RSpec.describe 'Accounts API', type: :request do | ||||
|         expect(response.body).to eq({ message: I18n.t('errors.signup.failed') }.to_json) | ||||
|       end | ||||
|     end | ||||
|  | ||||
|     context 'when ENABLE_ACCOUNT_SIGNUP env variable is set to false' do | ||||
|       let(:email) { Faker::Internet.email } | ||||
|  | ||||
|       it 'responds 404 on requests' do | ||||
|         params = { account_name: 'test', email: email } | ||||
|         ENV['ENABLE_ACCOUNT_SIGNUP'] = 'false' | ||||
|  | ||||
|         post api_v1_accounts_url, | ||||
|              params: params, | ||||
|              as: :json | ||||
|  | ||||
|         expect(response).to have_http_status(:not_found) | ||||
|         ENV['ENABLE_ACCOUNT_SIGNUP'] = nil | ||||
|       end | ||||
|     end | ||||
|  | ||||
|     context 'when ENABLE_ACCOUNT_SIGNUP env variable is set to api_only' do | ||||
|       let(:email) { Faker::Internet.email } | ||||
|  | ||||
|       it 'does not respond 404 on requests' do | ||||
|         params = { account_name: 'test', email: email } | ||||
|         ENV['ENABLE_ACCOUNT_SIGNUP'] = 'api_only' | ||||
|  | ||||
|         post api_v1_accounts_url, | ||||
|              params: params, | ||||
|              as: :json | ||||
|  | ||||
|         expect(response).not_to have_http_status(:not_found) | ||||
|         ENV['ENABLE_ACCOUNT_SIGNUP'] = nil | ||||
|       end | ||||
|     end | ||||
|   end | ||||
| end | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Sojan Jose
					Sojan Jose