Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Close #2047 implement JWT on email confirmation #2048

Merged
merged 1 commit into from
Dec 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
module Spree
module Api
module V2
module Storefront
class AnonymousOrderController < Spree::Api::V2::BaseController
def show_anonymous_order
token = params[:token]
order = order_jwt_token(token)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

order = CmCommissioner::OrderJwtToken.decode(token)


if order
render_serialized_payload { serialize_resource(order) }
else
render json: { error: 'Invalid or expired token' }, status: :unauthorized
end
end

def resource_serializer
Spree::V2::Storefront::OrderSerializer
end

private

def order_jwt_token(token)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's move this to libs/cm_commissioners/order_jwt_token.rb service

module CmCommissioner
  class OrderJwtToken
      def self.encode(order)
           # construct the payload to encode here
           # encode  and return jwt_token string
      end

      def self.decode(jwt_token)
           # decode and return order or nil is invalid
      end
   end
end






decoded_token = SpreeCmCommissioner::OrderJwtToken.decode(token)

order_number = decoded_token['order_number']
return nil unless order_number

order = Spree::Order.find_by(number: order_number)
return nil unless order

decoded_token = SpreeCmCommissioner::OrderJwtToken.decode(token, order&.token)
return nil unless decoded_token

order
end
end
end
end
end
end
17 changes: 17 additions & 0 deletions app/helpers/spree/base_helper_decorator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,23 @@ def custom_product_storefront_resource_url(resource, options = {})
spree_storefront_resource_url(resource)
end
end

def custom_product_line_item_url(line_item, jwt_token, options = {})
if defined?(locale_param) && locale_param.present?
options.merge!(locale: locale_param)
end

localize = if options[:locale].present?
"/#{options[:locale]}"
else
''
end

order = Spree::Order.find(line_item.order_id)
return if order.number.blank? && jwt_token.blank?

"#{current_store.formatted_url + localize}/anonymous_orders/#{jwt_token}"
end
end
end

Expand Down
2 changes: 2 additions & 0 deletions app/mailers/spree/order_mailer_decorator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ def confirm_email(order, resend: false)
subject = (resend ? "[#{Spree.t(:resend).upcase}] " : '')
subject += "#{@current_store&.name} Booking Confirmation ##{@order.number}"

@jwt_token = SpreeCmCommissioner::OrderJwtToken.encode(@order)

mail(to: @order.email, from: from_address, subject: subject, store_url: @current_store.url) do |format|
format.html { render layout: 'spree_cm_commissioner/layouts/order_mailer' }
format.text
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
<%= sanitize(line_item.variant.options_text) %>
</div>
<% end %>
<div> <%= link_to 'View Details', custom_product_line_item_url(line_item, @jwt_token) %></div>
</td>
<td class="align-right align-center-vertical" width="10%">
<span>
Expand Down
1 change: 1 addition & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -470,6 +470,7 @@
resources :self_check_in, only: %i[index create]
resources :guest_orders, only: %i[index show]
post :user_order_transfer, to: 'user_order_transfer#create'
get 'anonymous_order/show_anonymous_order', to: 'anonymous_order#show_anonymous_order'
end

namespace :operator do
Expand Down
1 change: 1 addition & 0 deletions lib/spree_cm_commissioner.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
require 'spree_cm_commissioner/payment_method_group'
require 'spree_cm_commissioner/calendar_event'
require 'spree_cm_commissioner/s3_url_generator'
require 'spree_cm_commissioner/order_jwt_token'

require 'google/cloud/recaptcha_enterprise'
require 'searchkick'
Expand Down
14 changes: 14 additions & 0 deletions lib/spree_cm_commissioner/order_jwt_token.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
module SpreeCmCommissioner
class OrderJwtToken
def self.encode(order)
payload = { order_number: order.number, user_id: order.user_id, exp: 1.hour.from_now.to_i }
JWT.encode(payload, order.token, 'HS256')
end

def self.decode(token, secret = nil)
JWT.decode(token, secret, secret.present?, { algorithm: 'HS256' }).first
rescue JWT::DecodeError
nil
end
end
end
Loading