add access tokens
This commit is contained in:
@@ -11,7 +11,7 @@ module Api
|
|||||||
user: current_user,
|
user: current_user,
|
||||||
source: :api,
|
source: :api,
|
||||||
send_email: params[:send_email] != 'false',
|
send_email: params[:send_email] != 'false',
|
||||||
emails: params[:emails])
|
emails: params[:emails] || params[:email])
|
||||||
else
|
else
|
||||||
Submissions.create_from_submitters(template:,
|
Submissions.create_from_submitters(template:,
|
||||||
user: current_user,
|
user: current_user,
|
||||||
|
|||||||
@@ -0,0 +1,39 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
# == Schema Information
|
||||||
|
#
|
||||||
|
# Table name: access_tokens
|
||||||
|
#
|
||||||
|
# id :bigint not null, primary key
|
||||||
|
# sha256 :text not null
|
||||||
|
# token :text not null
|
||||||
|
# created_at :datetime not null
|
||||||
|
# updated_at :datetime not null
|
||||||
|
# user_id :bigint not null
|
||||||
|
#
|
||||||
|
# Indexes
|
||||||
|
#
|
||||||
|
# index_access_tokens_on_sha256 (sha256) UNIQUE
|
||||||
|
# index_access_tokens_on_user_id (user_id)
|
||||||
|
#
|
||||||
|
# Foreign Keys
|
||||||
|
#
|
||||||
|
# fk_rails_... (user_id => users.id)
|
||||||
|
#
|
||||||
|
class AccessToken < ApplicationRecord
|
||||||
|
TOKEN_LENGTH = 22
|
||||||
|
|
||||||
|
belongs_to :user
|
||||||
|
|
||||||
|
before_validation :set_sha256, on: :create
|
||||||
|
|
||||||
|
attribute :token, :string, default: -> { SecureRandom.base58(TOKEN_LENGTH) }
|
||||||
|
|
||||||
|
encrypts :token
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def set_sha256
|
||||||
|
self.sha256 = Digest::SHA256.hexdigest(token)
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -45,6 +45,7 @@ class User < ApplicationRecord
|
|||||||
EMAIL_REGEXP = /[^@,\s]+@[^@,\s]+/
|
EMAIL_REGEXP = /[^@,\s]+@[^@,\s]+/
|
||||||
|
|
||||||
belongs_to :account
|
belongs_to :account
|
||||||
|
has_one :access_token, dependent: :destroy
|
||||||
|
|
||||||
devise :database_authenticatable, :recoverable, :rememberable, :validatable, :trackable
|
devise :database_authenticatable, :recoverable, :rememberable, :validatable, :trackable
|
||||||
devise :registerable, :omniauthable, omniauth_providers: [:google_oauth2] if Docuseal.multitenant?
|
devise :registerable, :omniauthable, omniauth_providers: [:google_oauth2] if Docuseal.multitenant?
|
||||||
@@ -54,6 +55,10 @@ class User < ApplicationRecord
|
|||||||
|
|
||||||
scope :active, -> { where(deleted_at: nil) }
|
scope :active, -> { where(deleted_at: nil) }
|
||||||
|
|
||||||
|
def access_token
|
||||||
|
super || build_access_token.tap(&:save!)
|
||||||
|
end
|
||||||
|
|
||||||
def active_for_authentication?
|
def active_for_authentication?
|
||||||
!deleted_at?
|
!deleted_at?
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
<div class="card-body p-6">
|
<div class="card-body p-6">
|
||||||
<label for="api_key" class="text-sm font-semibold">X-Auth-Token</label>
|
<label for="api_key" class="text-sm font-semibold">X-Auth-Token</label>
|
||||||
<div class="flex flex-row space-x-4">
|
<div class="flex flex-row space-x-4">
|
||||||
<input id="api_key" type="text" value="<%= jwt = JsonWebToken.encode(uuid: current_user.uuid, scope: :api) %>" class="input font-mono input-bordered w-full" autocomplete="off" readonly>
|
<input id="api_key" type="text" value="<%= current_user.access_token.token %>" class="input font-mono input-bordered w-full" autocomplete="off" readonly>
|
||||||
<%= render 'shared/clipboard_copy', icon: 'copy', text: jwt, class: 'base-button', icon_class: 'w-6 h-6 text-white', copy_title: 'Copy', copied_title: 'Copied' %>
|
<%= render 'shared/clipboard_copy', icon: 'copy', text: current_user.access_token.token, class: 'base-button', icon_class: 'w-6 h-6 text-white', copy_title: 'Copy', copied_title: 'Copied' %>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -26,7 +26,7 @@
|
|||||||
<div class="collapse-content" style="display: inherit">
|
<div class="collapse-content" style="display: inherit">
|
||||||
<div class="mockup-code overflow-hidden">
|
<div class="mockup-code overflow-hidden">
|
||||||
<% text = capture do %>curl --location '<%= api_submissions_url %>' \
|
<% text = capture do %>curl --location '<%= api_submissions_url %>' \
|
||||||
--header 'X-Auth-Token: <%= jwt %>' \
|
--header 'X-Auth-Token: <%= current_user.access_token.token %>' \
|
||||||
--data-raw '{
|
--data-raw '{
|
||||||
"template_id": <%= current_account.templates.last&.id || 1 %>,
|
"template_id": <%= current_account.templates.last&.id || 1 %>,
|
||||||
"emails": "<%= current_user.email.sub('@', '+test@') %>, <%= current_user.email.sub('@', '+test2@') %>"
|
"emails": "<%= current_user.email.sub('@', '+test@') %>, <%= current_user.email.sub('@', '+test2@') %>"
|
||||||
@@ -52,7 +52,7 @@
|
|||||||
<div class="collapse-content" style="display: inherit">
|
<div class="collapse-content" style="display: inherit">
|
||||||
<div class="mockup-code overflow-hidden">
|
<div class="mockup-code overflow-hidden">
|
||||||
<% text = capture do %>curl --location '<%= api_submissions_url %>' \
|
<% text = capture do %>curl --location '<%= api_submissions_url %>' \
|
||||||
--header 'X-Auth-Token: <%= jwt %>' \
|
--header 'X-Auth-Token: <%= current_user.access_token.token %>' \
|
||||||
--data-raw '{
|
--data-raw '{
|
||||||
"template_id": <%= current_account.templates.last&.id || 1 %>,
|
"template_id": <%= current_account.templates.last&.id || 1 %>,
|
||||||
"submission": [
|
"submission": [
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class CreateAccessTokens < ActiveRecord::Migration[7.0]
|
||||||
|
def change
|
||||||
|
create_table :access_tokens do |t|
|
||||||
|
t.references :user, null: false, foreign_key: true, index: true
|
||||||
|
t.text :token, null: false
|
||||||
|
t.text :sha256, null: false, index: { unique: true }
|
||||||
|
|
||||||
|
t.timestamps
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
+12
-1
@@ -10,10 +10,20 @@
|
|||||||
#
|
#
|
||||||
# It's strongly recommended that you check this file into your version control system.
|
# It's strongly recommended that you check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema[7.0].define(version: 2023_08_05_124454) do
|
ActiveRecord::Schema[7.0].define(version: 2023_08_06_140534) do
|
||||||
# These are extensions that must be enabled in order to support this database
|
# These are extensions that must be enabled in order to support this database
|
||||||
enable_extension "plpgsql"
|
enable_extension "plpgsql"
|
||||||
|
|
||||||
|
create_table "access_tokens", force: :cascade do |t|
|
||||||
|
t.bigint "user_id", null: false
|
||||||
|
t.text "token", null: false
|
||||||
|
t.text "sha256", null: false
|
||||||
|
t.datetime "created_at", null: false
|
||||||
|
t.datetime "updated_at", null: false
|
||||||
|
t.index ["sha256"], name: "index_access_tokens_on_sha256", unique: true
|
||||||
|
t.index ["user_id"], name: "index_access_tokens_on_user_id"
|
||||||
|
end
|
||||||
|
|
||||||
create_table "accounts", force: :cascade do |t|
|
create_table "accounts", force: :cascade do |t|
|
||||||
t.string "name", null: false
|
t.string "name", null: false
|
||||||
t.string "timezone", null: false
|
t.string "timezone", null: false
|
||||||
@@ -148,6 +158,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_08_05_124454) do
|
|||||||
t.index ["uuid"], name: "index_users_on_uuid", unique: true
|
t.index ["uuid"], name: "index_users_on_uuid", unique: true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
add_foreign_key "access_tokens", "users"
|
||||||
add_foreign_key "active_storage_attachments", "active_storage_blobs", column: "blob_id"
|
add_foreign_key "active_storage_attachments", "active_storage_blobs", column: "blob_id"
|
||||||
add_foreign_key "active_storage_variant_records", "active_storage_blobs", column: "blob_id"
|
add_foreign_key "active_storage_variant_records", "active_storage_blobs", column: "blob_id"
|
||||||
add_foreign_key "document_generation_events", "submitters"
|
add_foreign_key "document_generation_events", "submitters"
|
||||||
|
|||||||
@@ -6,9 +6,9 @@ class AuthWithTokenStrategy < Devise::Strategies::Base
|
|||||||
end
|
end
|
||||||
|
|
||||||
def authenticate!
|
def authenticate!
|
||||||
payload = JsonWebToken.decode(request.headers['X-Auth-Token'])
|
sha256 = Digest::SHA256.hexdigest(request.headers['X-Auth-Token'])
|
||||||
|
|
||||||
user = User.find_by(uuid: payload['uuid'])
|
user = User.joins(:access_token).find_by(access_token: { sha256: })
|
||||||
|
|
||||||
if user
|
if user
|
||||||
success!(user)
|
success!(user)
|
||||||
|
|||||||
Reference in New Issue
Block a user