Skip to content

Commit

Permalink
Issue 374 2 (#1450)
Browse files Browse the repository at this point in the history
* feat: generate udt verification model to save token

Signed-off-by: Miles Zhang <[email protected]>

* feat: set mailer for udt verify

Signed-off-by: Miles Zhang <[email protected]>

* feat: rename udt's contact_info to email

Signed-off-by: Miles Zhang <[email protected]>

* feat: update udt info and send token business logic

Signed-off-by: Miles Zhang <[email protected]>

---------

Signed-off-by: Miles Zhang <[email protected]>
  • Loading branch information
zmcNotafraid authored Sep 18, 2023
1 parent c308dec commit fa5ef5a
Show file tree
Hide file tree
Showing 22 changed files with 534 additions and 75 deletions.
31 changes: 31 additions & 0 deletions app/controllers/api/v1/udt_verifications_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
module Api
module V1
class UdtVerificationsController < ApplicationController
before_action :check_udt_info, only: :update
before_action :set_locale, only: :update

def update
udt_verification = UdtVerification.find_or_create_by(udt_id: @udt.id)

udt_verification.refresh_token!(request.remote_ip)
UdtVerificationMailer.with(email: @udt.email, token: udt_verification.token,
locale: @locale).send_token.deliver_later
render json: :ok
rescue UdtVerification::TokenSentTooFrequentlyError
raise Api::V1::Exceptions::TokenSentTooFrequentlyError
end

private

def check_udt_info
@udt = Udt.find_by(type_hash: params[:id])
raise Api::V1::Exceptions::UdtNotFoundError if @udt.nil?
raise Api::V1::Exceptions::UdtNoContactEmailError if @udt.email.blank?
end

def set_locale
@locale = params[:locale] == "zh_CN" ? "zh_CN" : "en"
end
end
end
end
17 changes: 15 additions & 2 deletions app/controllers/api/v1/udts_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,27 @@ def update
icon_file: params[:icon_file],
uan: params[:uan],
display_name: params[:display_name],
contact_info: params[:contact_info]
email: params[:email]
}
udt.update!(attrs)
if udt.email.blank?
raise Api::V1::Exceptions::UdtInfoInvalidError.new("Email can't be blank") if params[:email].blank?

udt.update!(attrs)
else
raise Api::V1::Exceptions::UdtVerificationNotFoundError if udt.udt_verification.nil?

udt.udt_verification.validate_token!(params[:token])
udt.update!(attrs)
end
render json: :ok
rescue ActiveRecord::RecordNotFound
raise Api::V1::Exceptions::UdtNotFoundError
rescue ActiveRecord::RecordInvalid => e
raise Api::V1::Exceptions::UdtInfoInvalidError.new(e)
rescue UdtVerification::TokenExpiredError
raise Api::V1::Exceptions::TokenExpiredError
rescue UdtVerification::TokenNotMatchError
raise Api::V1::Exceptions::TokenNotMatchError
end

def show
Expand Down
37 changes: 37 additions & 0 deletions app/lib/api/v1/exceptions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -174,11 +174,13 @@ def initialize
super code: 1027, status: 404, title: "URI parameters invalid", detail: "code hash should be start with 0x", href: "https://nervosnetwork.github.io/ckb-explorer/public/api_doc.html"
end
end

class ScriptHashTypeParamsInvalidError < Error
def initialize
super code: 1028, status: 404, title: "URI parameters invalid", detail: "hash type should be 'type'", href: "https://nervosnetwork.github.io/ckb-explorer/public/api_doc.html"
end
end

class ScriptNotFoundError < Error
def initialize
super code: 1029, status: 404, title: "Script not found", detail: "Script not found", href: "https://nervosnetwork.github.io/ckb-explorer/public/api_doc.html"
Expand All @@ -191,6 +193,41 @@ def initialize(detail)
end
end

class UdtVerificationInvalidError < Error
def initialize(detail)
super code: 1031, status: 400, title: "UDT verification invalid", detail: detail, href: "https://nervosnetwork.github.io/ckb-explorer/public/api_doc.html"
end
end

class UdtVerificationNotFoundError < Error
def initialize
super code: 1032, status: 404, title: "UDT Verification Not Found", detail: "No UDT verification records found by given type hash", href: "https://nervosnetwork.github.io/ckb-explorer/public/api_doc.html"
end
end

class UdtNoContactEmailError < Error
def initialize
super code: 1033, status: 400, title: "UDT has no contact email", detail: "", href: "https://nervosnetwork.github.io/ckb-explorer/public/api_doc.html"
end
end

class TokenExpiredError < Error
def initialize
super code: 1034, status: 400, title: "Token has expired", detail: "", href: "https://nervosnetwork.github.io/ckb-explorer/public/api_doc.html"
end
end

class TokenNotMatchError < Error
def initialize
super code: 1035, status: 400, title: "Token is not matched", detail: "", href: "https://nervosnetwork.github.io/ckb-explorer/public/api_doc.html"
end
end

class TokenSentTooFrequentlyError < Error
def initialize
super code: 1036, status: 400, title: "Token sent too frequently", detail: "", href: "https://nervosnetwork.github.io/ckb-explorer/public/api_doc.html"
end
end
end
end
end
12 changes: 12 additions & 0 deletions app/mailers/udt_verification_mailer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
class UdtVerificationMailer < ApplicationMailer
default from: "[email protected]"

def send_token
email = params[:email]
@token = params[:token]
locale = params[:locale] || "en"
I18n.with_locale(locale) do
mail(to: email, subject: "Token Info Verification")
end
end
end
8 changes: 6 additions & 2 deletions app/models/udt.rb
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
class Udt < ApplicationRecord
MAX_PAGINATES_PER = 100

belongs_to :nrc_factory_cell, optional: true

MAX_PAGINATES_PER = 100
has_one :udt_verification

enum udt_type: { sudt: 0, m_nft_token: 1, nrc_721_token: 2, spore_cell: 3 }

validates_presence_of :total_amount
validates_length_of :symbol, minimum: 1, maximum: 16, allow_nil: true
validates_length_of :full_name, minimum: 1, maximum: 100, allow_nil: true
validates :decimal, numericality: { greater_than_or_equal_to: 0, less_than_or_equal_to: 39 }, allow_nil: true
validates :total_amount, numericality: { greater_than_or_equal_to: 0 }
validates :email, format: { with: /\A(.+)@(.+)\z/, message: "Not a valid email" }, allow_nil: true

attribute :code_hash, :ckb_hash

Expand Down Expand Up @@ -60,7 +64,7 @@ def type_script
# display_name :string
# uan :string
# h24_ckb_transactions_count :bigint default(0)
# contact_info :string
# email :string
#
# Indexes
#
Expand Down
43 changes: 43 additions & 0 deletions app/models/udt_verification.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
class UdtVerification < ApplicationRecord
SENT_FREQUENCY_MINUTES = 1
KEEP_ALIVE_MINUTES = 10

class TokenExpiredError < StandardError; end
class TokenNotMatchError < StandardError; end
class TokenSentTooFrequentlyError < StandardError; end

belongs_to :udt

def refresh_token!(ip)
raise TokenSentTooFrequentlyError if sent_at.present? && self.sent_at + SENT_FREQUENCY_MINUTES.minutes > Time.now

self.token = rand(999999).to_s.rjust(6, "0")
self.sent_at = Time.now
self.last_ip = ip
self.save!
end

def validate_token!(token_params)
raise TokenExpiredError if self.sent_at + KEEP_ALIVE_MINUTES.minutes < Time.now
raise TokenNotMatchError if token != token_params.to_i
end
end

# == Schema Information
#
# Table name: udt_verifications
#
# id :bigint not null, primary key
# token :integer
# sent_at :datetime
# last_ip :inet
# udt_id :bigint
# udt_type_hash :integer
# created_at :datetime not null
# updated_at :datetime not null
#
# Indexes
#
# index_udt_verifications_on_udt_id (udt_id)
# index_udt_verifications_on_udt_type_hash (udt_type_hash) UNIQUE
#
12 changes: 12 additions & 0 deletions app/views/udt_verification_mailer/send_token.en.text.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
Dear Token Info Author,

To ensure the effectiveness of your Token Info modification operation, we have generated a verification code for you to complete the Token Info update.

Your verification code is: <%= @token %>

Please note that this verification code is only valid for the next 10 minutes. Please use it to complete your Token Info modification within this time frame and refrain from sharing your code with others. If you have not initiated any action or if this operation is not associated with you, please disregard this email.

If you have any questions or require assistance, please feel free to contact our customer support team.Thank you for your trust and support!

Best regards,
The MagicKBase Team
10 changes: 10 additions & 0 deletions app/views/udt_verification_mailer/send_token.zh_CN.text.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
尊敬的 Token Info 作者,

为了确保本次 Token Info 修改操作的有效性,我们为您生成了一个验证码,用于完成 Token Info 的修改操作。

您的验证码是:<%= @token %>

请注意,该验证码仅在接下来的10分钟内有效。请在此时间内完成 Token Info 的修改操作,并且请不要分享您的验证码给他人。如果您没有进行任何操作或者不是您的操作,请忽略此邮件。

如果您有任何疑问或需要帮助,请随时联系我们的客户支持团队。谢谢您的信任和支持!
MagicKBase 团队
14 changes: 13 additions & 1 deletion config/environments/production.rb
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,19 @@

# Ignore bad email addresses and do not raise email delivery errors.
# Set this to true and configure the email server for immediate delivery to raise delivery errors.
# config.action_mailer.raise_delivery_errors = false
config.action_mailer.raise_delivery_errors = true
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
address: ENV["SMTP_ADDRESS"],
port: ENV["SMTP_PORT"],
domain: "[email protected]",
user_name: ENV["SMTP_USER"],
password: ENV["SMTP_PASSWORD"],
authentication: "plain",
enable_starttls_auto: true,
open_timeout: 5,
read_timeout: 5
}

# Enable locale fallbacks for I18n (makes lookups for any locale fall back to
# the I18n.default_locale when a translation cannot be found).
Expand Down
2 changes: 2 additions & 0 deletions config/initializers/locales.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
I18n.available_locales = [:en, :zh_CN]
I18n.default_locale = :en
3 changes: 2 additions & 1 deletion config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
resources :block_statistics, only: :show ## TODO: unused route
resources :epoch_statistics, only: :show
resources :market_data, only: :show
resources :udts, only: %i(index show) do
resources :udts, only: %i(index show update) do
collection do
get :download_csv
end
Expand All @@ -60,6 +60,7 @@
resources :address_udt_transactions, only: :show
resources :distribution_data, only: :show
resources :monetary_data, only: :show
resources :udt_verifications, only: :update
end
end
draw "v2"
Expand Down
14 changes: 14 additions & 0 deletions db/migrate/20230913091025_create_udt_verifications.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
class CreateUdtVerifications < ActiveRecord::Migration[7.0]
def change
create_table :udt_verifications do |t|
t.integer :token
t.datetime :sent_at
t.inet :last_ip
t.belongs_to :udt
t.integer :udt_type_hash

t.timestamps
t.index :udt_type_hash, unique: true
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class ChangeContractInfoToEmailInUdt < ActiveRecord::Migration[7.0]
def change
rename_column :udts, :contact_info, :email
end
end
Loading

0 comments on commit fa5ef5a

Please sign in to comment.