improve registration and add oauth
This commit is contained in:
@@ -16,6 +16,8 @@ gem 'image_processing'
|
||||
gem 'lograge'
|
||||
gem 'mysql2', require: false
|
||||
gem 'oj'
|
||||
gem 'omniauth-google-oauth2'
|
||||
gem 'omniauth-rails_csrf_protection'
|
||||
gem 'pagy'
|
||||
gem 'pg', require: false
|
||||
gem 'premailer-rails'
|
||||
|
||||
@@ -232,6 +232,7 @@ GEM
|
||||
os (>= 0.9, < 2.0)
|
||||
signet (>= 0.16, < 2.a)
|
||||
hashdiff (1.0.1)
|
||||
hashie (5.0.0)
|
||||
hexapdf (0.32.2)
|
||||
cmdparse (~> 3.0, >= 3.0.3)
|
||||
geom2d (~> 0.3)
|
||||
@@ -282,6 +283,7 @@ GEM
|
||||
minitest (5.18.1)
|
||||
msgpack (1.7.1)
|
||||
multi_json (1.15.0)
|
||||
multi_xml (0.6.0)
|
||||
multipart-post (2.3.0)
|
||||
mysql2 (0.5.5)
|
||||
net-http-persistent (4.0.2)
|
||||
@@ -298,7 +300,29 @@ GEM
|
||||
nio4r (2.5.9)
|
||||
nokogiri (1.15.2-arm64-darwin)
|
||||
racc (~> 1.4)
|
||||
oauth2 (2.0.9)
|
||||
faraday (>= 0.17.3, < 3.0)
|
||||
jwt (>= 1.0, < 3.0)
|
||||
multi_xml (~> 0.5)
|
||||
rack (>= 1.2, < 4)
|
||||
snaky_hash (~> 2.0)
|
||||
version_gem (~> 1.1)
|
||||
oj (3.15.0)
|
||||
omniauth (2.1.1)
|
||||
hashie (>= 3.4.6)
|
||||
rack (>= 2.2.3)
|
||||
rack-protection
|
||||
omniauth-google-oauth2 (1.1.1)
|
||||
jwt (>= 2.0)
|
||||
oauth2 (~> 2.0.6)
|
||||
omniauth (~> 2.0)
|
||||
omniauth-oauth2 (~> 1.8.0)
|
||||
omniauth-oauth2 (1.8.0)
|
||||
oauth2 (>= 1.4, < 3)
|
||||
omniauth (~> 2.0)
|
||||
omniauth-rails_csrf_protection (1.0.1)
|
||||
actionpack (>= 4.2)
|
||||
omniauth (~> 2.0)
|
||||
openssl (3.1.0)
|
||||
orm_adapter (0.5.0)
|
||||
os (1.1.4)
|
||||
@@ -326,6 +350,8 @@ GEM
|
||||
nio4r (~> 2.0)
|
||||
racc (1.7.1)
|
||||
rack (2.2.7)
|
||||
rack-protection (3.0.6)
|
||||
rack
|
||||
rack-proxy (0.7.6)
|
||||
rack
|
||||
rack-test (2.1.0)
|
||||
@@ -444,6 +470,9 @@ GEM
|
||||
simplecov-html (0.12.3)
|
||||
simplecov_json_formatter (0.1.4)
|
||||
smart_properties (1.17.0)
|
||||
snaky_hash (2.0.1)
|
||||
hashie
|
||||
version_gem (~> 1.1, >= 1.1.1)
|
||||
sqlite3 (1.5.4)
|
||||
mini_portile2 (~> 2.8.0)
|
||||
strip_attributes (1.13.0)
|
||||
@@ -462,6 +491,7 @@ GEM
|
||||
uber (0.1.0)
|
||||
unicode-display_width (2.4.2)
|
||||
uniform_notifier (1.16.0)
|
||||
version_gem (1.1.3)
|
||||
warden (1.2.9)
|
||||
rack (>= 2.0.9)
|
||||
web-console (4.2.0)
|
||||
@@ -507,6 +537,8 @@ DEPENDENCIES
|
||||
lograge
|
||||
mysql2
|
||||
oj
|
||||
omniauth-google-oauth2
|
||||
omniauth-rails_csrf_protection
|
||||
pagy
|
||||
pg
|
||||
premailer-rails
|
||||
|
||||
@@ -40,6 +40,8 @@ class AccountsController < ApplicationController
|
||||
end
|
||||
|
||||
def app_url_params
|
||||
return {} if params[:encrypted_config].blank?
|
||||
|
||||
params.require(:encrypted_config).permit(:value)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -4,6 +4,7 @@ class DashboardController < ApplicationController
|
||||
skip_before_action :authenticate_user!, only: %i[index]
|
||||
|
||||
def index
|
||||
return redirect_to Docuseal::PRODUCT_URL, allow_other_host: true if Docuseal.multitenant? && !signed_in?
|
||||
return render 'pages/landing' unless signed_in?
|
||||
|
||||
templates = current_account.templates.active.preload(:author).order(id: :desc)
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class OmniauthCallbacksController < Devise::OmniauthCallbacksController
|
||||
def google_oauth2
|
||||
@user = Users.from_omniauth(request.env['omniauth.auth'])
|
||||
|
||||
if @user.persisted?
|
||||
flash[:notice] = I18n.t('devise.omniauth_callbacks.success', kind: 'Google')
|
||||
|
||||
sign_in_and_redirect @user, event: :authentication
|
||||
else
|
||||
redirect_to new_registration_path(oauth_callback: true, user: @user.slice(:email, :first_name, :last_name)),
|
||||
notice: 'Please complete registration with Google auth'
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,6 +1,16 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class RegistrationsController < Devise::RegistrationsController
|
||||
prepend_before_action :require_no_authentication, only: [:show]
|
||||
|
||||
def show; end
|
||||
|
||||
def create
|
||||
super
|
||||
|
||||
Accounts.create_default_template(resource.account) if resource.account.persisted?
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def build_resource(_hash = {})
|
||||
@@ -8,17 +18,21 @@ class RegistrationsController < Devise::RegistrationsController
|
||||
account.timezone = Accounts.normalize_timezone(account.timezone)
|
||||
|
||||
self.resource = account.users.new(user_params)
|
||||
|
||||
account.name ||= "#{resource.full_name}'s Company" if params[:action] == 'create'
|
||||
end
|
||||
|
||||
def user_params
|
||||
return {} if params[:user].blank?
|
||||
|
||||
params.require(:user).permit(:first_name, :last_name, :email, :password)
|
||||
params.require(:user).permit(:first_name, :last_name, :email, :password).compact_blank.tap do |attrs|
|
||||
attrs[:password] ||= SecureRandom.hex if params[:action] == 'create'
|
||||
end
|
||||
end
|
||||
|
||||
def account_params
|
||||
return {} if params[:account].blank?
|
||||
|
||||
params.require(:account).permit(:name, :timezone)
|
||||
params.require(:account).permit(:name, :timezone).compact_blank
|
||||
end
|
||||
end
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class SessionsController < Devise::SessionsController
|
||||
def create
|
||||
if Docuseal.multitenant? && !User.exists?(email: sign_in_params[:email])
|
||||
return redirect_to new_registration_path(sign_up: true, user: sign_in_params.slice(:email)),
|
||||
notice: 'Create a new account'
|
||||
end
|
||||
|
||||
super
|
||||
end
|
||||
end
|
||||
@@ -32,7 +32,7 @@ class Submitter < ApplicationRecord
|
||||
belongs_to :submission
|
||||
|
||||
attribute :values, :string, default: -> { {} }
|
||||
attribute :slug, :string, default: -> { SecureRandom.base58(10) }
|
||||
attribute :slug, :string, default: -> { SecureRandom.base58(14) }
|
||||
|
||||
serialize :values, JSON
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ class Template < ApplicationRecord
|
||||
attribute :fields, :string, default: -> { [] }
|
||||
attribute :schema, :string, default: -> { [] }
|
||||
attribute :submitters, :string, default: -> { [{ name: DEFAULT_SUBMITTER_NAME, uuid: SecureRandom.uuid }] }
|
||||
attribute :slug, :string, default: -> { SecureRandom.base58(10) }
|
||||
attribute :slug, :string, default: -> { SecureRandom.base58(14) }
|
||||
|
||||
serialize :fields, JSON
|
||||
serialize :schema, JSON
|
||||
|
||||
+1
-1
@@ -46,7 +46,7 @@ class User < ApplicationRecord
|
||||
belongs_to :account
|
||||
|
||||
devise :database_authenticatable, :recoverable, :rememberable, :validatable, :trackable
|
||||
devise :registerable if Docuseal.multitenant?
|
||||
devise :registerable, :omniauthable, omniauth_providers: [:google_oauth2] if Docuseal.multitenant?
|
||||
|
||||
attribute :role, :string, default: 'admin'
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<div class="max-w-xl mx-auto px-2">
|
||||
<h1 class="text-4xl font-bold text-center my-8">Sign up</h1>
|
||||
<%= form_for('', as: resource_name, html: { class: 'space-y-6' }, url: registration_path) do |f| %>
|
||||
<%= form_for('', as: resource_name, html: { class: 'space-y-6' }, url: new_registration_path) do |f| %>
|
||||
<div class="space-y-2">
|
||||
<%= render 'devise/shared/error_messages', resource: %>
|
||||
<%= f.fields_for resource do |ff| %>
|
||||
@@ -16,7 +16,7 @@
|
||||
</div>
|
||||
<% end %>
|
||||
<%= f.fields_for resource do |ff| %>
|
||||
<div class="form-control">
|
||||
<div class="form-control <%= 'hidden' if (params[:oauth_callback] || params[:sign_up]) && resource.email? %>">
|
||||
<%= ff.label :email, class: 'label' %>
|
||||
<%= ff.email_field :email, required: true, class: 'base-input' %>
|
||||
</div>
|
||||
@@ -25,14 +25,14 @@
|
||||
<set-timezone data-input-id="_account_timezone"></set-timezone>
|
||||
<%= ff.hidden_field :timezone %>
|
||||
<div class="form-control">
|
||||
<%= ff.label :name, 'Company name', class: 'label' %>
|
||||
<%= ff.text_field :name, required: true, class: 'base-input' %>
|
||||
<%= ff.label :name, 'Company name (optional)', class: 'label' %>
|
||||
<%= ff.text_field :name, class: 'base-input' %>
|
||||
</div>
|
||||
<% end %>
|
||||
<%= f.fields_for resource do |ff| %>
|
||||
<div class="form-control">
|
||||
<div class="form-control <%= 'hidden' if params[:oauth_callback] %>">
|
||||
<%= ff.label :password, class: 'label' %>
|
||||
<%= ff.password_field :password, required: true, class: 'base-input' %>
|
||||
<%= ff.password_field :password, required: !params[:oauth_callback], class: 'base-input' %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
<div class="max-w-xl mx-auto px-2">
|
||||
<h1 class="text-4xl font-bold text-center my-8">Sign up</h1>
|
||||
<%= form_for(User.new, html: { class: 'space-y-6' }, url: new_registration_path, method: :get) do |f| %>
|
||||
<div class="space-y-2">
|
||||
<div class="form-control">
|
||||
<%= f.label :email, class: 'label' %>
|
||||
<%= f.email_field :email, autofocus: true, autocomplete: 'email', class: 'base-input' %>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-control">
|
||||
<%= f.button button_title(title: 'Sign up', disabled_with: 'Sign up'), name: 'sign_up', value: true, class: 'base-button' %>
|
||||
</div>
|
||||
<% end %>
|
||||
<% if devise_mapping.omniauthable? %>
|
||||
<%= button_to button_title(title: 'Sign up with Google', icon: svg_icon('brand_google', class: 'w-6 h-6')), omniauth_authorize_path(resource_name, :google_oauth2), class: 'white-button w-full mt-4', data: { turbo: false }, method: :post %>
|
||||
<% end %>
|
||||
<%= render 'devise/shared/links' %>
|
||||
</div>
|
||||
@@ -23,5 +23,8 @@
|
||||
<%= f.button button_title(title: 'Log In', disabled_with: 'Logging In'), class: 'base-button' %>
|
||||
</div>
|
||||
<% end %>
|
||||
<% if devise_mapping.omniauthable? %>
|
||||
<%= button_to button_title(title: 'Log in with Google', icon: svg_icon('brand_google', class: 'w-6 h-6')), omniauth_authorize_path(resource_name, :google_oauth2), class: 'white-button w-full mt-4', data: { turbo: false }, method: :post %>
|
||||
<% end %>
|
||||
<%= render 'devise/shared/links' %>
|
||||
</div>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<%= link_to 'Log in', new_session_path(resource_name), class: 'link link-hover' %>
|
||||
<% end %>
|
||||
<%- if devise_mapping.registerable? && controller_name != 'registrations' %>
|
||||
<%= link_to 'Sign up', new_registration_path, class: 'link link-hover' %>
|
||||
<%= link_to 'Sign up', registration_path, class: 'link link-hover' %>
|
||||
<% end %>
|
||||
<%- if devise_mapping.recoverable? && controller_name != 'passwords' && controller_name != 'registrations' %>
|
||||
<%= link_to 'Forgot your password?', new_password_path(resource_name), class: 'link link-hover' %>
|
||||
@@ -14,9 +14,4 @@
|
||||
<%- if devise_mapping.lockable? && resource_class.unlock_strategy_enabled?(:email) && controller_name != 'unlocks' %>
|
||||
<%= link_to "Didn't receive unlock instructions?", new_unlock_path(resource_name), class: 'link link-hover' %>
|
||||
<% end %>
|
||||
<%- if devise_mapping.omniauthable? %>
|
||||
<%- resource_class.omniauth_providers.each do |provider| %>
|
||||
<%= button_to "Sign in with #{OmniAuth::Utils.camelize(provider)}", omniauth_authorize_path(resource_name, provider), class: 'link link-hover', data: { turbo: false } %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
<svg width="800" height="800" viewBox="-0.5 0 48 48" version="1.1" xmlns="http://www.w3.org/2000/svg" class="<%= local_assigns[:class] %>">
|
||||
<g id="Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="Color-" transform="translate(-401.000000, -860.000000)">
|
||||
<g id="Google" transform="translate(401.000000, 860.000000)">
|
||||
<path d="M9.82727273,24 C9.82727273,22.4757333 10.0804318,21.0144 10.5322727,19.6437333 L2.62345455,13.6042667 C1.08206818,16.7338667 0.213636364,20.2602667 0.213636364,24 C0.213636364,27.7365333 1.081,31.2608 2.62025,34.3882667 L10.5247955,28.3370667 C10.0772273,26.9728 9.82727273,25.5168 9.82727273,24" id="Fill-1" fill="#FBBC05">
|
||||
</path>
|
||||
<path d="M23.7136364,10.1333333 C27.025,10.1333333 30.0159091,11.3066667 32.3659091,13.2266667 L39.2022727,6.4 C35.0363636,2.77333333 29.6954545,0.533333333 23.7136364,0.533333333 C14.4268636,0.533333333 6.44540909,5.84426667 2.62345455,13.6042667 L10.5322727,19.6437333 C12.3545909,14.112 17.5491591,10.1333333 23.7136364,10.1333333" id="Fill-2" fill="#EB4335">
|
||||
</path>
|
||||
<path d="M23.7136364,37.8666667 C17.5491591,37.8666667 12.3545909,33.888 10.5322727,28.3562667 L2.62345455,34.3946667 C6.44540909,42.1557333 14.4268636,47.4666667 23.7136364,47.4666667 C29.4455,47.4666667 34.9177955,45.4314667 39.0249545,41.6181333 L31.5177727,35.8144 C29.3995682,37.1488 26.7323182,37.8666667 23.7136364,37.8666667" id="Fill-3" fill="#34A853">
|
||||
</path>
|
||||
<path d="M46.1454545,24 C46.1454545,22.6133333 45.9318182,21.12 45.6113636,19.7333333 L23.7136364,19.7333333 L23.7136364,28.8 L36.3181818,28.8 C35.6879545,31.8912 33.9724545,34.2677333 31.5177727,35.8144 L39.0249545,41.6181333 C43.3393409,37.6138667 46.1454545,31.6490667 46.1454545,24" id="Fill-4" fill="#4285F4">
|
||||
</path>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.8 KiB |
@@ -29,8 +29,8 @@
|
||||
<% end %>
|
||||
</li>
|
||||
<li>
|
||||
<%= link_to destroy_user_session_path, data: { turbo_method: :delete } do %>
|
||||
<%= svg_icon('logout', class: 'w-5 h-5 stroke-2') %>
|
||||
<%= button_to destroy_user_session_path, method: :delete, data: { turbo: false } do %>
|
||||
<%= svg_icon('logout', class: 'w-5 h-5 stroke-2 inline') %>
|
||||
<span class="mr-1">Sign out</span>
|
||||
<% end %>
|
||||
</li>
|
||||
|
||||
@@ -266,7 +266,7 @@ Devise.setup do |config|
|
||||
# ==> OmniAuth
|
||||
# Add a new OmniAuth provider. Check the wiki for more information on setting
|
||||
# up on your models and hooks.
|
||||
# config.omniauth :github, 'APP_ID', 'APP_SECRET', scope: 'user,public_repo'
|
||||
config.omniauth :google_oauth2, ENV.fetch('GOOGLE_CLIENT_ID', nil), ENV.fetch('GOOGLE_CLIENT_SECRET', nil), {}
|
||||
|
||||
# ==> Warden configuration
|
||||
# If you want to use other strategies, that are not supported by Devise, or
|
||||
|
||||
+9
-2
@@ -5,11 +5,18 @@ Rails.application.routes.draw do
|
||||
|
||||
root 'dashboard#index'
|
||||
|
||||
devise_for :users, path: '/', only: %i[sessions passwords]
|
||||
devise_for :users,
|
||||
path: '/', only: %i[sessions passwords omniauth_callbacks],
|
||||
controllers: begin
|
||||
options = { sessions: 'sessions' }
|
||||
options[:omniauth_callbacks] = 'omniauth_callbacks' if Docuseal.multitenant?
|
||||
options
|
||||
end
|
||||
|
||||
devise_scope :user do
|
||||
if Docuseal.multitenant?
|
||||
resource :registration, only: %i[create], path: 'sign_up' do
|
||||
resource :registration, only: %i[show], path: 'sign_up'
|
||||
resource :registration, only: %i[create], path: 'new' do
|
||||
get '' => :new, as: :new
|
||||
end
|
||||
end
|
||||
|
||||
+15
-1
@@ -16,7 +16,7 @@ module Accounts
|
||||
new_template = template.dup
|
||||
|
||||
new_template.account = new_account
|
||||
new_template.slug = SecureRandom.base58(10)
|
||||
new_template.slug = SecureRandom.base58(14)
|
||||
|
||||
new_template.save!
|
||||
|
||||
@@ -28,6 +28,20 @@ module Accounts
|
||||
new_account
|
||||
end
|
||||
|
||||
def create_default_template(account)
|
||||
template = Template.find(1)
|
||||
|
||||
new_template = Template.find(1).dup
|
||||
new_template.account_id = account.id
|
||||
new_template.slug = SecureRandom.base58(14)
|
||||
|
||||
new_template.save!
|
||||
|
||||
Templates::CloneAttachments.call(template: new_template, original_template: template)
|
||||
|
||||
new_template
|
||||
end
|
||||
|
||||
def load_signing_certs(account)
|
||||
certs =
|
||||
if Docuseal.multitenant?
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Users
|
||||
module_function
|
||||
|
||||
def from_omniauth(oauth)
|
||||
user = User.find_by(email: oauth.info.email)
|
||||
|
||||
return user if user
|
||||
|
||||
User.new(email: oauth.info.email,
|
||||
first_name: oauth.extra.id_info.given_name,
|
||||
last_name: oauth.extra.id_info.family_name)
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user