Skip to content

Instantly share code, notes, and snippets.

@mazz
Last active February 6, 2024 21:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mazz/d62bc53c59c2120ba3fcfaa6b2df95c3 to your computer and use it in GitHub Desktop.
Save mazz/d62bc53c59c2120ba3fcfaa6b2df95c3 to your computer and use it in GitHub Desktop.
passwordless_auth_live.ex
defp handle_validation(socket, {:ok, _user_pin}) do
Accounts.UserPin.purge_pins(socket.assigns.auth_user)
sign_in_token =
socket.assigns.auth_user
|> Accounts.generate_user_session_token()
|> Base.encode64()
# sign_in_token is still valid up to here
dbg(sign_in_token)
token_changeset =
build_token_changeset(%{
sign_in_token: sign_in_token,
user_return_to: socket.assigns.user_return_to
})
# sign_in_token is still valid up to here
dbg(token_changeset)
socket
|> assign(:trigger_submit, true)
|> assign(:token_form, to_form(token_changeset, as: :auth))
end
[lib/faithful_word/metrics/worker.ex:73: FaithfulWord.Metrics.Worker.upsert!/2]
path #=> "/auth/sign-in/passwordless"
[lib/faithful_word/metrics/worker.ex:74: FaithfulWord.Metrics.Worker.upsert!/2]
counter #=> 1
[debug] QUERY OK source="metrics" db=2.8ms queue=1.2ms idle=1671.6ms
INSERT INTO "metrics" AS m0 ("date","path","counter") VALUES ($1,$2,$3) ON CONFLICT ("date","path") DO UPDATE SET "counter" = m0."counter" + $4 [~D[2024-02-06], "/auth/sign-in/passwordless", 1, 1]
↳ :gen_server.try_terminate/3, at: gen_server.erl:1125
[debug] HANDLE EVENT "validate_pin" in FaithfulWordWeb.PasswordlessAuthLive
Parameters: %{"_csrf_token" => "PRx5FDQRBQQSPiAgAhsBJ3gRNA09W2FfkqIzQPMaaSNUfaUN1VrbR5-3", "_target" => ["auth", "pin"], "auth" => %{"pin" => "388172", "sign_in_token" => "", "user_return_to" => ""}}
[debug] QUERY OK source="users_pins" db=1.1ms queue=0.1ms idle=1370.5ms
SELECT u0."id", u0."hashed_pin", u0."attempts", u0."user_id", u0."inserted_at", u0."updated_at" FROM "users_pins" AS u0 WHERE (u0."user_id" = $1) ["1eebf40f-5fa3-63f0-8b5d-716c9079fd6d"]
↳ FaithfulWord.Accounts.UserPin.validate_pin/3, at: lib/faithful_word/accounts/user_pin.ex:80
[debug] QUERY OK source="users_pins" db=3.3ms idle=1372.6ms
DELETE FROM "users_pins" AS u0 WHERE ((u0."user_id" = $1)) OR (u0."inserted_at" < $2::timestamp + (-(10)::numeric * interval '1 minute')) ["1eebf40f-5fa3-63f0-8b5d-716c9079fd6d", ~U[2024-02-06 21:03:52.756651Z]]
↳ FaithfulWordWeb.PasswordlessAuthLive.handle_validation/2, at: lib/faithful_word_web/live/auth/passwordless_auth_live.ex:238
[(faithful_word 1.5.1) lib/faithful_word_web/live/auth/passwordless_auth_live.ex:245: FaithfulWordWeb.PasswordlessAuthLive.handle_validation/2]
sign_in_token #=> "4Kp7obKci7xtyukv1OwGXwaFdb+F7SelzzqBlfSM7us="
[debug] QUERY OK source="users_tokens" db=2.2ms queue=0.5ms idle=1376.3ms
INSERT INTO "users_tokens" ("context","token","user_id","id","inserted_at") VALUES ($1,$2,$3,$4,$5) ["session", <<224, 170, 123, 161, 178, 156, 139, 188, 109, 202, 233, 47, 212, 236, 6, 95, 6, 133, 117, 191, 133, 237, 39, 165, 207, 58, 129, 149, 244, 140, 238, 235>>, "1eebf40f-5fa3-63f0-8b5d-716c9079fd6d", "1eec5333-b847-68d4-b5d5-0c5b2e359f55", ~N[2024-02-06 21:03:52]]
↳ FaithfulWord.Accounts.generate_user_session_token/1, at: lib/faithful_word/accounts.ex:1067
[(faithful_word 1.5.1) lib/faithful_word_web/live/auth/passwordless_auth_live.ex:253: FaithfulWordWeb.PasswordlessAuthLive.handle_validation/2]
token_changeset #=> #Ecto.Changeset<
action: nil,
changes: %{sign_in_token: "4Kp7obKci7xtyukv1OwGXwaFdb+F7SelzzqBlfSM7us="},
errors: [],
data: %{},
valid?: true
>
[debug] Replied in 16ms
[info] short_links_maybe_redirect
[info] POST /auth/sign-in/passwordless
[debug] Processing with FaithfulWordWeb.UserSessionController.create_from_token/2
Parameters: %{"_csrf_token" => "PRx5FDQRBQQSPiAgAhsBJ3gRNA09W2FfkqIzQPMaaSNUfaUN1VrbR5-3", "auth" => %{"pin" => "388172", "sign_in_token" => "", "user_return_to" => ""}}
Pipelines: [:browser, :redirect_if_user_is_authenticated]
[lib/faithful_word_web/router.ex:197: FaithfulWordWeb.Router.put_accept_language_into_session/2]
headers["accept-language"] #=> "en-CA,en-US;q=0.7,en;q=0.3"
[lib/faithful_word_web/controllers/user_session_controller.ex:62: FaithfulWordWeb.UserSessionController.create_from_token/2]
sign_in_token #=> ""
[lib/faithful_word_web/controllers/user_session_controller.ex:63: FaithfulWordWeb.UserSessionController.create_from_token/2]
params #=> %{"pin" => "388172", "sign_in_token" => "", "user_return_to" => ""}
[debug] QUERY OK source="users_tokens" db=0.4ms idle=845.2ms
SELECT u1."id", u1."first_name", u1."last_name", u1."username", u1."mobile_number", u1."email", u1."hashed_password", u1."confirmed_at", u1."gender", u1."birthdate", u1."is_admin", u1."avatar", u1."last_signed_in_ip", u1."last_signed_in_datetime", u1."is_subscribed_to_marketing_notifications", u1."is_suspended", u1."is_deleted", u1."is_onboarded", u1."is_permanently_deleted", u1."enforce_otp", u1."client_preferences", u1."admin_org_slug", u1."billing_subscription_stripe", u1."billing_subscription_storekit", u1."inserted_at", u1."updated_at" FROM "users_tokens" AS u0 INNER JOIN "users" AS u1 ON u1."id" = u0."user_id" WHERE ((u0."token" = $1) AND (u0."context" = $2)) AND (u0."inserted_at" > $3::timestamp + (-(60)::numeric * interval '1 day')) ["", "session", ~U[2024-02-06 21:03:52.905350Z]]
↳ FaithfulWordWeb.UserSessionController.create_from_token/2, at: lib/faithful_word_web/controllers/user_session_controller.ex:67
[info] Sent 302 in 1ms
[info] short_links_maybe_redirect
[info] GET /auth/sign-in/passwordless
[lib/faithful_word_web/router.ex:197: FaithfulWordWeb.Router.put_accept_language_into_session/2]
headers["accept-language"] #=> "en-CA,en-US;q=0.7,en;q=0.3"
[debug] Processing with FaithfulWordWeb.PasswordlessAuthLive.sign_in/2
Parameters: %{}
Pipelines: [:browser, :redirect_if_user_is_authenticated]
[(faithful_word 1.5.1) lib/faithful_word_web/live/auth/passwordless_auth_live.ex:45: FaithfulWordWeb.PasswordlessAuthLive.handle_params/3]
params #=> %{}
[(faithful_word 1.5.1) lib/faithful_word_web/live/auth/passwordless_auth_live.ex:46: FaithfulWordWeb.PasswordlessAuthLive.handle_params/3]
socket.assigns.live_action #=> :sign_in
[lib/faithful_word/metrics/metrics.ex:35: FaithfulWord.Metrics.bump/1]
path #=> "/auth/sign-in/passwordless"
<.form
for={@token_form}
action={~p"/auth/sign-in/passwordless"}
phx-trigger-action={@trigger_submit}
phx-change="validate_pin"
class={if @trigger_submit, do: "hidden", else: ""}
>
<.form_label><%= gettext("Your sign in pin code") %></.form_label>
<input
type="number"
name={@token_form[:pin].name}
value={@token_form[:pin].value}
class="block w-full font-mono text-center border-gray-300 rounded-md shadow-sm md:text-2xl dark:bg-gray-800 dark:text-gray-300 dark:border-gray-600 focus:border-primary-500 dark:focus:border-primary-500 focus:outline-none focus:ring-primary-500"
min="0"
max="10000000"
inputmode="numeric"
pattern="[0-9]*"
onkeypress="{if(this.value.length==6) return false;}"
autofill="off"
autocomplete="off"
{alpine_autofocus()}
/>
<.input type="hidden" field={@token_form[:sign_in_token]} />
<.input type="hidden" field={@token_form[:user_return_to]} />
<.alert color="warning" class="mt-5" label={@error_message} />
<div class="flex justify-between mt-6">
<.button
to={~p"/auth/sign-in/passwordless"}
link_type="live_patch"
type="button"
color="white"
>
<.icon solid name={:arrow_small_left} class="w-4 h-4 mr-1" />
<%= gettext("Cancel") %>
</.button>
<%= if @enable_resend? do %>
<.button
color="white"
type="button"
phx-disable-with={gettext("Resending new pin code...")}
phx-click="resend"
>
<.icon solid name={:arrow_path} class="w-4 h-4 mr-1" />
<%= gettext("Resend pin code") %>
</.button>
<% end %>
</div>
</.form>
@mazz
Copy link
Author

mazz commented Feb 6, 2024

hi all, still working on a (now) legacy 1.5.1 Petal codebase. So far so good but when I upgraded plug_cowboy to 2.7 submitting a passwordless login pin will now fail.

The issue is the PasswordessAuthLive.handle_validation() submits an empty string for sign_in_token to POST /auth/sign-in/passwordless

it has something to do with the to_form() in:

    socket
    |> assign(:trigger_submit, true)
    |> assign(:token_form, to_form(token_changeset, as: :auth))

I know for sure it's the plug_cowboy upgrade 2.5 -> 2.7 because when I rollback to 2.5 login is OK. Any suggestions?

I put the chunks of code in a gist:

https://gist.github.com/mazz/d62bc53c59c2120ba3fcfaa6b2df95c3

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment