Skip to content
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
20 changes: 20 additions & 0 deletions assets/js/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -623,3 +623,23 @@ window.addEventListener("phx:js-exec", ({ detail }) => {
liveSocket.execJS(el, el.getAttribute(detail.attr));
});
});

window.addEventListener("phx:open_popup", (e: CustomEvent) => {
const url = e.detail.url;
if (!url) return;

const width = e.detail.width || 600;
const height = e.detail.height || 600;
const left = e.detail.left || window.screen.width / 2 - width / 2;
const top = e.detail.top || window.screen.height / 2 - height / 2;

const newWindow = window.open(
url,
"oauth",
`width=${width},height=${height},left=${left},top=${top},toolbar=0,scrollbars=1,status=1`
);

if (window.focus && newWindow) {
newWindow.focus();
}
});
68 changes: 39 additions & 29 deletions lib/algora_web/controllers/oauth_callback_controller.ex
Original file line number Diff line number Diff line change
Expand Up @@ -14,44 +14,54 @@ defmodule AlgoraWeb.OAuthCallbackController do
end
end

def translate_error(:invalid), do: "Unable to verify your login request. Please try signing in again"
def translate_error(:expired), do: "Your login link has expired. Please request a new one to continue"
def translate_error(%Ecto.Changeset{}), do: "We were unable to fetch the necessary information from your GitHub account"
def translate_error(_reason), do: "We were unable to contact GitHub. Please try again later"

def new(conn, %{"provider" => "github", "code" => code, "state" => state}) do
with {:ok, data} <- Github.verify_oauth_state(state),
{:ok, info} <- Github.OAuth.exchange_access_token(code: code, state: state),
%{info: info, primary_email: primary, emails: emails, token: token} = info,
{:ok, user} <- Accounts.register_github_user(primary, info, emails, token) do
conn =
case data[:return_to] do
nil -> conn
return_to -> put_session(conn, :user_return_to, return_to)
end
res = Github.verify_oauth_state(state)

conn
|> put_flash(:info, welcome_message(user))
|> AlgoraWeb.UserAuth.log_in_user(user)
else
{:error, :invalid} ->
conn
|> put_flash(:error, "Unable to verify your login request. Please try signing in again.")
|> redirect(to: "/")
socket_id =
case res do
{:ok, %{socket_id: socket_id}} -> socket_id
_ -> nil
end

{:error, :expired} ->
conn
|> put_flash(:error, "Your login link has expired. Please request a new one to continue.")
|> redirect(to: "/")
type = if(socket_id, do: :popup, else: :redirect)

{:error, %Ecto.Changeset{} = changeset} ->
Logger.debug("failed GitHub insert #{inspect(changeset.errors)}")
with {:ok, data} <- res,
{:ok, info} <- Github.OAuth.exchange_access_token(code: code, state: state),
%{info: info, primary_email: primary, emails: emails, token: token} = info,
{:ok, user} <- Accounts.register_github_user(primary, info, emails, token) do
if socket_id do
Phoenix.PubSub.broadcast(Algora.PubSub, "auth:#{socket_id}", {:authenticated, user})
end

conn
|> put_flash(:error, "We were unable to fetch the necessary information from your GitHub account")
|> redirect(to: "/")
case type do
:popup ->
conn
|> AlgoraWeb.UserAuth.put_current_user(user)
|> render(:success)

:redirect ->
conn
|> put_flash(:info, welcome_message(user))
|> AlgoraWeb.UserAuth.put_current_user(user)
|> redirect(to: data[:return_to] || AlgoraWeb.UserAuth.signed_in_path(conn))
end
else
{:error, reason} ->
Logger.debug("failed GitHub exchange #{inspect(reason)}")
conn = put_flash(conn, :error, translate_error(reason))

conn
|> put_flash(:error, "We were unable to contact GitHub. Please try again later")
|> redirect(to: "/")
case type do
:popup ->
render(conn, :error)

:redirect ->
redirect(conn, to: "/")
end
end
end

Expand Down
5 changes: 5 additions & 0 deletions lib/algora_web/controllers/oauth_callback_html.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
defmodule AlgoraWeb.OAuthCallbackHTML do
use AlgoraWeb, :html

embed_templates "oauth_callback_html/*"
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<div class="text-center p-8">
<h2 class="text-xl font-semibold text-destructive">Authentication Failed</h2>
<p>Please try again.</p>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<script>
window.close();
</script>
<div class="text-center p-8">
<h2 class="text-xl font-semibold text-success">Authentication Successful!</h2>
<p>You can close this window.</p>
</div>
20 changes: 12 additions & 8 deletions lib/algora_web/controllers/user_auth.ex
Original file line number Diff line number Diff line change
Expand Up @@ -86,16 +86,20 @@ defmodule AlgoraWeb.UserAuth do
"""
def log_in_user(conn, user) do
user_return_to = get_session(conn, :user_return_to)
conn = assign(conn, :current_user, user)

conn =
conn
|> renew_session()
|> put_session(:user_id, user.id)
|> put_session(:last_context, user.last_context)
|> put_session(:live_socket_id, "users_sessions:#{user.id}")
conn
|> put_current_user(user)
|> redirect(to: user_return_to || signed_in_path(conn))
end

redirect(conn, to: user_return_to || signed_in_path(conn))
def put_current_user(conn, user) do
conn = assign(conn, :current_user, user)

conn
|> renew_session()
|> put_session(:user_id, user.id)
|> put_session(:last_context, user.last_context)
|> put_session(:live_socket_id, "users_sessions:#{user.id}")
end

defp renew_session(conn) do
Expand Down
Loading
Loading