smbCloud Auth confirmation

Seto Elkahfi committed Jun 17, 2026 at 15:25 UTC 91b0d1e003b7709feb01a2183880e5d001e14966
3 files changed +80
app/controllers/confirmations_controller.rb
+16
@@ -7,6 +7,22 @@ class ConfirmationsController < ApplicationController
7 def new
8 end
9
10 + # GET /auth/confirmed
11 + # Landing page for the link in the confirmation email. smbCloud verifies the
12 + # token on its side, then redirects here with ?status=success or
13 + # ?status=failed&message=... (see redirect_or_render_confirmation in the
14 + # smbCloud client auth_users controller).
15 + def confirmed
16 + @succeeded = params[:status].to_s == "success"
17 + @message = params[:message].to_s.strip.presence
18 +
19 + # "Already confirmed" is a benign state, not a real failure: the account is
20 + # fine and the user just needs to sign in. smbCloud reports it as
21 + # status=failed with this message, so detect it and treat it gently rather
22 + # than showing the scary failure UI with a pointless "resend" button.
23 + @already_confirmed = !@succeeded && @message.to_s.match?(/already confirmed/i)
24 + end
25 +
26 # POST /auth/confirmation/resend
27 def create
28 email = params[:email].to_s.strip.downcase
app/views/confirmations/confirmed.html.erb new
+60
@@ -0,0 +1,60 @@
1 +<% content_for :title, @succeeded ? "Email confirmed" : (@already_confirmed ? "Already confirmed" : "Confirmation failed") %>
2 +
3 +<div class="min-h-screen bg-surface-900 flex flex-col items-center justify-center px-4 py-16">
4 +
5 + <div class="mb-10 flex flex-col items-center gap-3">
6 + <%= link_to root_path, class: "flex items-center gap-3 text-gray-100 hover:text-brand-500 transition-colors" do %>
7 + <img src="/icon.png" alt="siGit" class="h-9 w-auto">
8 + <span class="text-xl font-semibold tracking-tight">Code &amp; Deploy</span>
9 + <% end %>
10 + </div>
11 +
12 + <div class="w-full max-w-sm">
13 + <div class="border border-surface-500 rounded bg-surface-700 px-8 py-8 text-center">
14 +
15 + <% if @succeeded %>
16 + <div class="mx-auto mb-5 flex h-12 w-12 items-center justify-center rounded-full bg-green-900/30 text-green-400">
17 + <svg class="w-6 h-6" viewBox="0 0 16 16" fill="currentColor">
18 + <path d="M8 1a7 7 0 1 0 0 14A7 7 0 0 0 8 1zm3.78 5.28-4.5 4.5a.75.75 0 0 1-1.06 0l-2-2a.75.75 0 1 1 1.06-1.06l1.47 1.47 3.97-3.97a.75.75 0 1 1 1.06 1.06z"/>
19 + </svg>
20 + </div>
21 + <h1 class="text-lg font-semibold text-gray-100">Email confirmed</h1>
22 + <p class="mt-2 text-sm text-gray-400 leading-relaxed">
23 + Your account is ready. Sign in to start hosting code and models.
24 + </p>
25 + <%= link_to "Sign in", signin_path, class: "btn-primary w-full justify-center py-2.5 mt-6" %>
26 +
27 + <% elsif @already_confirmed %>
28 + <div class="mx-auto mb-5 flex h-12 w-12 items-center justify-center rounded-full bg-brand-500/15 text-brand-400">
29 + <svg class="w-6 h-6" viewBox="0 0 16 16" fill="currentColor">
30 + <path d="M8 1a7 7 0 1 0 0 14A7 7 0 0 0 8 1zm3.78 5.28-4.5 4.5a.75.75 0 0 1-1.06 0l-2-2a.75.75 0 1 1 1.06-1.06l1.47 1.47 3.97-3.97a.75.75 0 1 1 1.06 1.06z"/>
31 + </svg>
32 + </div>
33 + <h1 class="text-lg font-semibold text-gray-100">You're all set</h1>
34 + <p class="mt-2 text-sm text-gray-400 leading-relaxed">
35 + This email is already confirmed. Just sign in to continue.
36 + </p>
37 + <%= link_to "Sign in", signin_path, class: "btn-primary w-full justify-center py-2.5 mt-6" %>
38 +
39 + <% else %>
40 + <div class="mx-auto mb-5 flex h-12 w-12 items-center justify-center rounded-full bg-red-900/30 text-red-400">
41 + <svg class="w-6 h-6" viewBox="0 0 16 16" fill="currentColor">
42 + <path d="M8 1a7 7 0 1 1 0 14A7 7 0 0 1 8 1zm0 3.75a.75.75 0 0 0-.75.75v3.5a.75.75 0 0 0 1.5 0v-3.5A.75.75 0 0 0 8 4.75zm0 7.5a.875.875 0 1 0 0-1.75.875.875 0 0 0 0 1.75z"/>
43 + </svg>
44 + </div>
45 + <h1 class="text-lg font-semibold text-gray-100">Confirmation failed</h1>
46 + <p class="mt-2 text-sm text-gray-400 leading-relaxed">
47 + <%= @message || "This confirmation link is invalid or has expired. You can request a new one." %>
48 + </p>
49 + <%= link_to "Resend confirmation email", resend_confirmation_path, class: "btn-primary w-full justify-center py-2.5 mt-6" %>
50 + <% end %>
51 +
52 + </div>
53 +
54 + <p class="mt-6 text-center text-xs text-gray-500">
55 + Back to
56 + <%= link_to "Sign in", signin_path, class: "text-gray-400 hover:text-gray-200 underline underline-offset-2" %>
57 + </p>
58 + </div>
59 +
60 +</div>
config/routes.rb
+4
@@ -25,6 +25,10 @@ Rails.application.routes.draw do
25 get "/auth/signup", to: "registrations#new", as: :signup
26 post "/auth/signup", to: "registrations#create", as: :signup_create
27
28 + # Email confirmation landing — smbCloud confirms the token server-side, then
29 + # redirects here with ?status=success or ?status=failed&message=...
30 + get "/auth/confirmed", to: "confirmations#confirmed", as: :auth_confirmed
31 +
32 # Resend confirmation email
33 get "/auth/confirmation/resend", to: "confirmations#new", as: :resend_confirmation
34 post "/auth/confirmation/resend", to: "confirmations#create"