Unify Google sign-in and registration flow
Some checks are pending
Quality / full-local-gates (push) Waiting to run
Some checks are pending
Quality / full-local-gates (push) Waiting to run
This commit is contained in:
parent
ff856f637f
commit
811ddf4c5c
|
|
@ -819,6 +819,14 @@ defmodule WhoNeedHelp.Accounts do
|
||||||
UserNotifier.deliver_login_instructions(user, magic_link_url_fun.(encoded_token))
|
UserNotifier.deliver_login_instructions(user, magic_link_url_fun.(encoded_token))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@doc "Delivers a one-time local-account verification link before connecting Google."
|
||||||
|
def deliver_google_link_instructions(%User{} = user, magic_link_url_fun)
|
||||||
|
when is_function(magic_link_url_fun, 1) do
|
||||||
|
{encoded_token, user_token} = UserToken.build_email_token(user, "login")
|
||||||
|
Repo.insert!(user_token)
|
||||||
|
UserNotifier.deliver_google_link_instructions(user, magic_link_url_fun.(encoded_token))
|
||||||
|
end
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Deletes the signed token with the given context.
|
Deletes the signed token with the given context.
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,21 @@ defmodule WhoNeedHelp.Accounts.UserNotifier do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@doc "Delivers instructions for verifying a local account before connecting Google sign-in."
|
||||||
|
def deliver_google_link_instructions(user, url) do
|
||||||
|
with_user_locale(user, fn ->
|
||||||
|
deliver(
|
||||||
|
user.email,
|
||||||
|
gettext("Confirm Google sign-in"),
|
||||||
|
gettext(
|
||||||
|
"Hi %{email},\n\nUse the secure link below to sign in and connect Google to your Who Need Help account:\n\n%{url}\n\nIf you did not request this, ignore this email. Google will not be connected.",
|
||||||
|
email: user.email,
|
||||||
|
url: url
|
||||||
|
)
|
||||||
|
)
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
defp deliver_magic_link_instructions(user, url) do
|
defp deliver_magic_link_instructions(user, url) do
|
||||||
with_user_locale(user, fn ->
|
with_user_locale(user, fn ->
|
||||||
deliver(
|
deliver(
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ defmodule WhoNeedHelpWeb.GoogleAuthController do
|
||||||
|
|
||||||
alias WhoNeedHelp.{Accounts, GoogleAuth, Repo, Trust}
|
alias WhoNeedHelp.{Accounts, GoogleAuth, Repo, Trust}
|
||||||
alias WhoNeedHelp.Trust.RateLimiter
|
alias WhoNeedHelp.Trust.RateLimiter
|
||||||
alias WhoNeedHelpWeb.UserAuth
|
alias WhoNeedHelpWeb.{GoogleAuthPending, UserAuth}
|
||||||
|
|
||||||
import WhoNeedHelpWeb.UserAuth, only: [require_sudo_mode: 2]
|
import WhoNeedHelpWeb.UserAuth, only: [require_sudo_mode: 2]
|
||||||
|
|
||||||
|
|
@ -16,7 +16,12 @@ defmodule WhoNeedHelpWeb.GoogleAuthController do
|
||||||
plug :require_sudo_mode when action in [:start_link, :disconnect]
|
plug :require_sudo_mode when action in [:start_link, :disconnect]
|
||||||
|
|
||||||
def start_login(conn, _params) do
|
def start_login(conn, _params) do
|
||||||
start_flow(conn, "login", %{}, ~p"/users/log-in")
|
start_flow(
|
||||||
|
conn,
|
||||||
|
"login",
|
||||||
|
%{"locale" => Gettext.get_locale(WhoNeedHelpWeb.Gettext)},
|
||||||
|
~p"/users/log-in"
|
||||||
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
def start_registration(conn, %{"google_registration" => params}) when is_map(params) do
|
def start_registration(conn, %{"google_registration" => params}) when is_map(params) do
|
||||||
|
|
@ -70,6 +75,130 @@ defmodule WhoNeedHelpWeb.GoogleAuthController do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def complete(conn, _params) do
|
||||||
|
case GoogleAuthPending.fetch(conn) do
|
||||||
|
{:ok, pending} ->
|
||||||
|
case Accounts.get_user_by_email(pending.email) do
|
||||||
|
%Accounts.User{moderation_status: :suspended} ->
|
||||||
|
conn
|
||||||
|
|> GoogleAuthPending.delete()
|
||||||
|
|> google_account_unavailable(~p"/users/log-in")
|
||||||
|
|
||||||
|
existing_account ->
|
||||||
|
render(conn, :complete,
|
||||||
|
pending: pending,
|
||||||
|
existing_account: not is_nil(existing_account)
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
{:error, _reason} ->
|
||||||
|
conn
|
||||||
|
|> GoogleAuthPending.delete()
|
||||||
|
|> put_flash(:error, gettext("Google sign-in session expired. Please start again."))
|
||||||
|
|> redirect(to: ~p"/users/log-in")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def complete_registration(conn, %{"google_registration" => params}) when is_map(params) do
|
||||||
|
terms_accepted = params["terms_accepted"] in [true, "true", "on", "1"]
|
||||||
|
|
||||||
|
with true <- terms_accepted,
|
||||||
|
{:ok, pending} <- GoogleAuthPending.fetch(conn),
|
||||||
|
nil <- Accounts.get_user_by_email(pending.email),
|
||||||
|
{:ok, _limit} <- RateLimiter.check(:registration_email, pending.email),
|
||||||
|
{:ok, {user, _identity}} <-
|
||||||
|
Accounts.register_user_by_google(identity_attrs(pending), %{
|
||||||
|
"locale" => normalize_locale(params["locale"] || pending.locale),
|
||||||
|
"terms_accepted" => true
|
||||||
|
}) do
|
||||||
|
conn
|
||||||
|
|> GoogleAuthPending.delete()
|
||||||
|
|> put_flash(:info, gettext("Your account was created with Google."))
|
||||||
|
|> UserAuth.log_in_user(user)
|
||||||
|
else
|
||||||
|
false ->
|
||||||
|
conn
|
||||||
|
|> put_flash(
|
||||||
|
:error,
|
||||||
|
gettext("Confirm that you are 18 or older and accept the safety rules first.")
|
||||||
|
)
|
||||||
|
|> redirect(to: ~p"/auth/google/complete")
|
||||||
|
|
||||||
|
%Accounts.User{} ->
|
||||||
|
conn
|
||||||
|
|> put_flash(
|
||||||
|
:info,
|
||||||
|
gettext("This email already has an account. Confirm it once to connect Google.")
|
||||||
|
)
|
||||||
|
|> redirect(to: ~p"/auth/google/complete")
|
||||||
|
|
||||||
|
{:error, :rate_limited} ->
|
||||||
|
conn
|
||||||
|
|> put_flash(
|
||||||
|
:error,
|
||||||
|
gettext("Too many registration attempts in the configured time window.")
|
||||||
|
)
|
||||||
|
|> redirect(to: ~p"/auth/google/complete")
|
||||||
|
|
||||||
|
{:error, :missing} ->
|
||||||
|
expired_pending_redirect(conn)
|
||||||
|
|
||||||
|
{:error, :invalid_or_expired} ->
|
||||||
|
expired_pending_redirect(conn)
|
||||||
|
|
||||||
|
{:error, :email_already_registered} ->
|
||||||
|
conn
|
||||||
|
|> put_flash(
|
||||||
|
:info,
|
||||||
|
gettext("This email already has an account. Confirm it once to connect Google.")
|
||||||
|
)
|
||||||
|
|> redirect(to: ~p"/auth/google/complete")
|
||||||
|
|
||||||
|
{:error, _reason} ->
|
||||||
|
google_account_unavailable(conn, ~p"/users/log-in")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def complete_registration(conn, _params) do
|
||||||
|
conn
|
||||||
|
|> put_flash(:error, gettext("The Google registration form is invalid."))
|
||||||
|
|> redirect(to: ~p"/auth/google/complete")
|
||||||
|
end
|
||||||
|
|
||||||
|
def verify_existing(conn, _params) do
|
||||||
|
with {:ok, pending} <- GoogleAuthPending.fetch(conn),
|
||||||
|
%Accounts.User{moderation_status: status} = user when status != :suspended <-
|
||||||
|
Accounts.get_user_by_email(pending.email),
|
||||||
|
{:ok, pending_token} <- GoogleAuthPending.token(conn),
|
||||||
|
{:ok, _limit} <- RateLimiter.check(:magic_link_email, pending.email),
|
||||||
|
{:ok, _email} <- deliver_google_verification(conn, user, pending_token) do
|
||||||
|
conn
|
||||||
|
|> put_flash(
|
||||||
|
:info,
|
||||||
|
gettext(
|
||||||
|
"We sent a verification link to %{email}. Open it to finish connecting Google.",
|
||||||
|
email: pending.email
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|> redirect(to: ~p"/users/log-in")
|
||||||
|
else
|
||||||
|
{:error, :rate_limited} ->
|
||||||
|
conn
|
||||||
|
|> put_flash(
|
||||||
|
:error,
|
||||||
|
gettext("Too many sign-in emails in the configured time window.")
|
||||||
|
)
|
||||||
|
|> redirect(to: ~p"/auth/google/complete")
|
||||||
|
|
||||||
|
{:error, reason} when reason in [:missing, :invalid_or_expired] ->
|
||||||
|
expired_pending_redirect(conn)
|
||||||
|
|
||||||
|
_missing_suspended_or_delivery_error ->
|
||||||
|
Logger.warning("Unable to send Google account verification instructions")
|
||||||
|
google_account_unavailable(conn, ~p"/users/log-in")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def callback(conn, params) do
|
def callback(conn, params) do
|
||||||
flow = get_session(conn, @session_key)
|
flow = get_session(conn, @session_key)
|
||||||
conn = delete_session(conn, @session_key)
|
conn = delete_session(conn, @session_key)
|
||||||
|
|
@ -130,7 +259,7 @@ defmodule WhoNeedHelpWeb.GoogleAuthController do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
defp finish_flow(conn, "login", _flow, identity_attrs) do
|
defp finish_flow(conn, "login", flow, identity_attrs) do
|
||||||
case Accounts.login_user_by_google(identity_attrs) do
|
case Accounts.login_user_by_google(identity_attrs) do
|
||||||
{:ok, user} ->
|
{:ok, user} ->
|
||||||
conn
|
conn
|
||||||
|
|
@ -138,14 +267,10 @@ defmodule WhoNeedHelpWeb.GoogleAuthController do
|
||||||
|> UserAuth.log_in_user(user)
|
|> UserAuth.log_in_user(user)
|
||||||
|
|
||||||
{:error, :not_linked} ->
|
{:error, :not_linked} ->
|
||||||
conn
|
case GoogleAuthPending.put(conn, identity_attrs, flow_locale(flow)) do
|
||||||
|> put_flash(
|
{:ok, conn} -> redirect(conn, to: ~p"/auth/google/complete")
|
||||||
:error,
|
{:error, _reason} -> google_account_unavailable(conn, ~p"/users/log-in")
|
||||||
gettext(
|
end
|
||||||
"This Google account is not connected yet. Create an account or sign in by email and connect Google in account settings."
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|> redirect(to: ~p"/users/log-in")
|
|
||||||
|
|
||||||
{:error, _reason} ->
|
{:error, _reason} ->
|
||||||
google_account_unavailable(conn, ~p"/users/log-in")
|
google_account_unavailable(conn, ~p"/users/log-in")
|
||||||
|
|
@ -164,14 +289,18 @@ defmodule WhoNeedHelpWeb.GoogleAuthController do
|
||||||
|> UserAuth.log_in_user(user)
|
|> UserAuth.log_in_user(user)
|
||||||
else
|
else
|
||||||
{:error, :email_already_registered} ->
|
{:error, :email_already_registered} ->
|
||||||
|
case GoogleAuthPending.put(conn, identity_attrs, flow_locale(flow)) do
|
||||||
|
{:ok, conn} ->
|
||||||
conn
|
conn
|
||||||
|> put_flash(
|
|> put_flash(
|
||||||
:error,
|
:info,
|
||||||
gettext(
|
gettext("This email already has an account. Confirm it once to connect Google.")
|
||||||
"An account with this email already exists. Sign in by email or password, then connect Google in account settings."
|
|
||||||
)
|
)
|
||||||
)
|
|> redirect(to: ~p"/auth/google/complete")
|
||||||
|> redirect(to: ~p"/users/log-in")
|
|
||||||
|
{:error, _reason} ->
|
||||||
|
google_account_unavailable(conn, ~p"/users/log-in")
|
||||||
|
end
|
||||||
|
|
||||||
{:error, :rate_limited} ->
|
{:error, :rate_limited} ->
|
||||||
conn
|
conn
|
||||||
|
|
@ -255,6 +384,22 @@ defmodule WhoNeedHelpWeb.GoogleAuthController do
|
||||||
|> redirect(to: failure_path(flow))
|
|> redirect(to: failure_path(flow))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp deliver_google_verification(conn, user, pending_token) do
|
||||||
|
login_url = url(conn, ~p"/users/log-in")
|
||||||
|
|
||||||
|
Accounts.deliver_google_link_instructions(
|
||||||
|
user,
|
||||||
|
&"#{login_url}?google_link=#{URI.encode_www_form(pending_token)}#token=#{URI.encode_www_form(&1)}"
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp expired_pending_redirect(conn) do
|
||||||
|
conn
|
||||||
|
|> GoogleAuthPending.delete()
|
||||||
|
|> put_flash(:error, gettext("Google sign-in session expired. Please start again."))
|
||||||
|
|> redirect(to: ~p"/users/log-in")
|
||||||
|
end
|
||||||
|
|
||||||
defp google_account_unavailable(conn, path) do
|
defp google_account_unavailable(conn, path) do
|
||||||
conn
|
conn
|
||||||
|> put_flash(:error, gettext("This Google account cannot be used right now."))
|
|> put_flash(:error, gettext("This Google account cannot be used right now."))
|
||||||
|
|
@ -270,6 +415,12 @@ defmodule WhoNeedHelpWeb.GoogleAuthController do
|
||||||
defp normalize_locale(locale) when locale in @supported_locales, do: locale
|
defp normalize_locale(locale) when locale in @supported_locales, do: locale
|
||||||
defp normalize_locale(_locale), do: "en"
|
defp normalize_locale(_locale), do: "en"
|
||||||
|
|
||||||
|
defp flow_locale(flow), do: normalize_locale(flow["locale"])
|
||||||
|
|
||||||
|
defp identity_attrs(pending) do
|
||||||
|
Map.take(pending, [:provider_uid, :email, :email_verified, :display_name])
|
||||||
|
end
|
||||||
|
|
||||||
defp error_name(error) when is_atom(error), do: Atom.to_string(error)
|
defp error_name(error) when is_atom(error), do: Atom.to_string(error)
|
||||||
defp error_name(%{__struct__: module}), do: inspect(module)
|
defp error_name(%{__struct__: module}), do: inspect(module)
|
||||||
defp error_name(_error), do: "unknown_error"
|
defp error_name(_error), do: "unknown_error"
|
||||||
|
|
|
||||||
5
lib/who_need_help_web/controllers/google_auth_html.ex
Normal file
5
lib/who_need_help_web/controllers/google_auth_html.ex
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
defmodule WhoNeedHelpWeb.GoogleAuthHTML do
|
||||||
|
use WhoNeedHelpWeb, :html
|
||||||
|
|
||||||
|
embed_templates "google_auth_html/*"
|
||||||
|
end
|
||||||
|
|
@ -0,0 +1,103 @@
|
||||||
|
<Layouts.app flash={@flash} current_scope={@current_scope}>
|
||||||
|
<div class="mx-auto max-w-md space-y-5">
|
||||||
|
<div class="text-center">
|
||||||
|
<.header>
|
||||||
|
{gettext("Continue with Google")}
|
||||||
|
<:subtitle>
|
||||||
|
{gettext("Google verified your identity. Finish this one-time step to continue.")}
|
||||||
|
</:subtitle>
|
||||||
|
</.header>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="rounded-2xl border border-base-300 bg-base-100 p-4 shadow-sm">
|
||||||
|
<div class="flex items-center gap-3">
|
||||||
|
<span
|
||||||
|
class="flex size-10 items-center justify-center rounded-full bg-base-200"
|
||||||
|
aria-hidden="true"
|
||||||
|
>
|
||||||
|
<span class="text-lg font-bold text-brand">G</span>
|
||||||
|
</span>
|
||||||
|
<div class="min-w-0">
|
||||||
|
<p class="truncate font-semibold">{@pending.display_name}</p>
|
||||||
|
<p class="truncate text-sm text-base-content/65">{@pending.email}</p>
|
||||||
|
</div>
|
||||||
|
<span class="badge badge-success badge-outline ml-auto shrink-0">
|
||||||
|
{gettext("Verified")}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<%= if @existing_account do %>
|
||||||
|
<section class="space-y-4 rounded-2xl bg-base-200 p-5">
|
||||||
|
<div>
|
||||||
|
<h2 class="font-semibold">{gettext("This email already has an account")}</h2>
|
||||||
|
<p class="mt-2 text-sm text-base-content/70">
|
||||||
|
{gettext(
|
||||||
|
"Confirm access once so nobody can attach Google to your account using only a matching email address."
|
||||||
|
)}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<.form for={%{}} as={:google_verification} action={~p"/auth/google/verify-existing"}>
|
||||||
|
<.button class="btn btn-primary w-full" phx-disable-with={gettext("Sending...")}>
|
||||||
|
{gettext("Email me a verification link")} <span aria-hidden="true">→</span>
|
||||||
|
</.button>
|
||||||
|
</.form>
|
||||||
|
|
||||||
|
<.link navigate={~p"/users/log-in"} class="btn btn-ghost w-full">
|
||||||
|
{gettext("Use my password instead")}
|
||||||
|
</.link>
|
||||||
|
|
||||||
|
<p class="text-xs text-base-content/60">
|
||||||
|
{gettext("After this confirmation, future Google sign-ins will take one click.")}
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
<% else %>
|
||||||
|
<section class="space-y-4 rounded-2xl bg-base-200 p-5">
|
||||||
|
<div>
|
||||||
|
<h2 class="font-semibold">{gettext("Create your Who Need Help account")}</h2>
|
||||||
|
<p class="mt-2 text-sm text-base-content/70">
|
||||||
|
{gettext("No password is required. Google will be connected as your sign-in method.")}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<.form
|
||||||
|
for={%{}}
|
||||||
|
as={:google_registration}
|
||||||
|
action={~p"/auth/google/complete-registration"}
|
||||||
|
class="space-y-3"
|
||||||
|
>
|
||||||
|
<input type="hidden" name="google_registration[locale]" value={@pending.locale} />
|
||||||
|
<.input
|
||||||
|
type="checkbox"
|
||||||
|
id="google_completion_terms"
|
||||||
|
name="google_registration[terms_accepted]"
|
||||||
|
value="false"
|
||||||
|
label={gettext("I am 18 or older and accept the Terms and Safety Rules")}
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
<p class="text-xs text-base-content/60">
|
||||||
|
{gettext("Read the")}
|
||||||
|
<.link href={~p"/terms"} class="link font-semibold">{gettext("Terms")}</.link>,
|
||||||
|
<.link href={~p"/privacy"} class="link font-semibold">{gettext("Privacy Policy")}</.link>
|
||||||
|
{gettext("and")}
|
||||||
|
<.link href={~p"/safety"} class="link font-semibold">{gettext("Safety Rules")}</.link>
|
||||||
|
{gettext("before confirming.")}
|
||||||
|
</p>
|
||||||
|
<.button
|
||||||
|
class="btn btn-primary w-full"
|
||||||
|
phx-disable-with={gettext("Creating account...")}
|
||||||
|
>
|
||||||
|
{gettext("Create account and continue")} <span aria-hidden="true">→</span>
|
||||||
|
</.button>
|
||||||
|
</.form>
|
||||||
|
</section>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<div class="text-center">
|
||||||
|
<.link href={~p"/users/log-in"} class="link text-sm">
|
||||||
|
{gettext("Cancel and use another sign-in method")}
|
||||||
|
</.link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Layouts.app>
|
||||||
|
|
@ -5,16 +5,22 @@ defmodule WhoNeedHelpWeb.UserSessionController do
|
||||||
|
|
||||||
alias WhoNeedHelp.{Accounts, GoogleAuth}
|
alias WhoNeedHelp.{Accounts, GoogleAuth}
|
||||||
alias WhoNeedHelp.Trust.RateLimiter
|
alias WhoNeedHelp.Trust.RateLimiter
|
||||||
alias WhoNeedHelpWeb.UserAuth
|
alias WhoNeedHelpWeb.{GoogleAuthPending, UserAuth}
|
||||||
|
|
||||||
plug :assign_magic_link_form
|
plug :assign_magic_link_form
|
||||||
plug :put_no_store
|
plug :put_no_store
|
||||||
|
|
||||||
def new(conn, _params) do
|
def new(conn, params) do
|
||||||
email = get_in(conn.assigns, [:current_scope, Access.key(:user), Access.key(:email)])
|
conn = maybe_restore_pending_google(conn, params)
|
||||||
|
pending_google_email = pending_google_email(conn)
|
||||||
|
|
||||||
|
email =
|
||||||
|
get_in(conn.assigns, [:current_scope, Access.key(:user), Access.key(:email)]) ||
|
||||||
|
pending_google_email
|
||||||
|
|
||||||
form = Phoenix.Component.to_form(%{"email" => email}, as: "user")
|
form = Phoenix.Component.to_form(%{"email" => email}, as: "user")
|
||||||
|
|
||||||
render(conn, :new, form: form)
|
render(conn, :new, form: form, pending_google_email: pending_google_email)
|
||||||
end
|
end
|
||||||
|
|
||||||
# magic link login
|
# magic link login
|
||||||
|
|
@ -30,6 +36,7 @@ defmodule WhoNeedHelpWeb.UserSessionController do
|
||||||
{:ok, {user, _expired_tokens}} ->
|
{:ok, {user, _expired_tokens}} ->
|
||||||
conn
|
conn
|
||||||
|> put_flash(:info, info)
|
|> put_flash(:info, info)
|
||||||
|
|> maybe_connect_pending_google(user)
|
||||||
|> UserAuth.log_in_user(user, user_params)
|
|> UserAuth.log_in_user(user, user_params)
|
||||||
|
|
||||||
{:error, :not_found} ->
|
{:error, :not_found} ->
|
||||||
|
|
@ -49,6 +56,7 @@ defmodule WhoNeedHelpWeb.UserSessionController do
|
||||||
if user = Accounts.get_user_by_email_and_password(email, password) do
|
if user = Accounts.get_user_by_email_and_password(email, password) do
|
||||||
conn
|
conn
|
||||||
|> put_flash(:info, gettext("Welcome back!"))
|
|> put_flash(:info, gettext("Welcome back!"))
|
||||||
|
|> maybe_connect_pending_google(user)
|
||||||
|> UserAuth.log_in_user(user, user_params)
|
|> UserAuth.log_in_user(user, user_params)
|
||||||
else
|
else
|
||||||
invalid_password_response(conn, user_params)
|
invalid_password_response(conn, user_params)
|
||||||
|
|
@ -125,6 +133,48 @@ defmodule WhoNeedHelpWeb.UserSessionController do
|
||||||
|> render(:new, form: Phoenix.Component.to_form(user_params, as: "user"))
|
|> render(:new, form: Phoenix.Component.to_form(user_params, as: "user"))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp maybe_restore_pending_google(conn, %{"google_link" => token}) when is_binary(token) do
|
||||||
|
case GoogleAuthPending.restore(conn, token) do
|
||||||
|
{:ok, conn} -> conn
|
||||||
|
{:error, conn, _reason} -> conn
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp maybe_restore_pending_google(conn, _params), do: conn
|
||||||
|
|
||||||
|
defp pending_google_email(conn) do
|
||||||
|
case GoogleAuthPending.fetch(conn) do
|
||||||
|
{:ok, pending} -> pending.email
|
||||||
|
{:error, _reason} -> nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp maybe_connect_pending_google(conn, user) do
|
||||||
|
case GoogleAuthPending.connect(conn, user) do
|
||||||
|
{:ok, conn, _identity} ->
|
||||||
|
put_flash(
|
||||||
|
conn,
|
||||||
|
:info,
|
||||||
|
gettext("Google sign-in connected. You can use it next time.")
|
||||||
|
)
|
||||||
|
|
||||||
|
{:error, conn, :missing} ->
|
||||||
|
conn
|
||||||
|
|
||||||
|
{:error, conn, :invalid_or_expired} ->
|
||||||
|
conn
|
||||||
|
|
||||||
|
{:error, conn, _reason} ->
|
||||||
|
put_flash(
|
||||||
|
conn,
|
||||||
|
:error,
|
||||||
|
gettext(
|
||||||
|
"You are signed in, but Google could not be connected. Try again in account settings."
|
||||||
|
)
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
defp assign_magic_link_form(conn, _opts) do
|
defp assign_magic_link_form(conn, _opts) do
|
||||||
conn
|
conn
|
||||||
|> assign(
|
|> assign(
|
||||||
|
|
@ -132,6 +182,7 @@ defmodule WhoNeedHelpWeb.UserSessionController do
|
||||||
Phoenix.Component.to_form(%{"token" => ""}, as: "user")
|
Phoenix.Component.to_form(%{"token" => ""}, as: "user")
|
||||||
)
|
)
|
||||||
|> assign(:google_auth_enabled, GoogleAuth.enabled?())
|
|> assign(:google_auth_enabled, GoogleAuth.enabled?())
|
||||||
|
|> assign(:pending_google_email, pending_google_email(conn))
|
||||||
end
|
end
|
||||||
|
|
||||||
defp put_no_store(conn, _opts), do: put_resp_header(conn, "cache-control", "no-store")
|
defp put_no_store(conn, _opts), do: put_resp_header(conn, "cache-control", "no-store")
|
||||||
|
|
|
||||||
|
|
@ -71,7 +71,7 @@
|
||||||
id="google_login_form"
|
id="google_login_form"
|
||||||
>
|
>
|
||||||
<.google_auth_button
|
<.google_auth_button
|
||||||
label={gettext("Sign in with Google")}
|
label={gettext("Continue with Google")}
|
||||||
disabled={!@google_auth_enabled}
|
disabled={!@google_auth_enabled}
|
||||||
/>
|
/>
|
||||||
<p :if={!@google_auth_enabled} class="mt-2 text-center text-xs text-base-content/55">
|
<p :if={!@google_auth_enabled} class="mt-2 text-center text-xs text-base-content/55">
|
||||||
|
|
@ -81,6 +81,16 @@
|
||||||
|
|
||||||
<div :if={!@current_scope} class="divider">{gettext("or use email")}</div>
|
<div :if={!@current_scope} class="divider">{gettext("or use email")}</div>
|
||||||
|
|
||||||
|
<p
|
||||||
|
:if={@pending_google_email && !@current_scope}
|
||||||
|
class="mb-4 rounded-2xl bg-base-200 p-4 text-sm text-base-content/70"
|
||||||
|
>
|
||||||
|
{gettext(
|
||||||
|
"Sign in to %{email} once to connect Google. You can use the email link or your existing password.",
|
||||||
|
email: @pending_google_email
|
||||||
|
)}
|
||||||
|
</p>
|
||||||
|
|
||||||
<.form :let={f} for={@form} as={:user} id="login_form_magic" action={~p"/users/log-in"}>
|
<.form :let={f} for={@form} as={:user} id="login_form_magic" action={~p"/users/log-in"}>
|
||||||
<.input
|
<.input
|
||||||
readonly={!!@current_scope}
|
readonly={!!@current_scope}
|
||||||
|
|
|
||||||
128
lib/who_need_help_web/google_auth_pending.ex
Normal file
128
lib/who_need_help_web/google_auth_pending.ex
Normal file
|
|
@ -0,0 +1,128 @@
|
||||||
|
defmodule WhoNeedHelpWeb.GoogleAuthPending do
|
||||||
|
@moduledoc false
|
||||||
|
|
||||||
|
import Plug.Conn
|
||||||
|
|
||||||
|
alias WhoNeedHelp.{Accounts, Repo, Trust}
|
||||||
|
|
||||||
|
@session_key "pending_google_identity"
|
||||||
|
@token_salt "pending-google-identity"
|
||||||
|
@max_age_seconds 15 * 60
|
||||||
|
@supported_locales ~w(en uk ru)
|
||||||
|
|
||||||
|
def put(conn, identity_attrs, locale \\ "en") do
|
||||||
|
with {:ok, payload} <- normalize(identity_attrs, locale) do
|
||||||
|
token = Phoenix.Token.sign(WhoNeedHelpWeb.Endpoint, @token_salt, payload)
|
||||||
|
{:ok, put_session(conn, @session_key, token)}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def fetch(conn) do
|
||||||
|
conn
|
||||||
|
|> get_session(@session_key)
|
||||||
|
|> verify_token()
|
||||||
|
end
|
||||||
|
|
||||||
|
def restore(conn, token) when is_binary(token) do
|
||||||
|
case verify_token(token) do
|
||||||
|
{:ok, _pending} -> {:ok, put_session(conn, @session_key, token)}
|
||||||
|
{:error, reason} -> {:error, conn, reason}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def restore(conn, _token), do: {:error, conn, :invalid}
|
||||||
|
|
||||||
|
def token(conn) do
|
||||||
|
case fetch(conn) do
|
||||||
|
{:ok, _pending} -> {:ok, get_session(conn, @session_key)}
|
||||||
|
{:error, reason} -> {:error, reason}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def delete(conn), do: delete_session(conn, @session_key)
|
||||||
|
|
||||||
|
def connect(conn, user) do
|
||||||
|
with {:ok, pending} <- fetch(conn),
|
||||||
|
true <- normalized_email(user.email) == pending.email,
|
||||||
|
{:ok, identity} <- connect_and_audit(user, pending) do
|
||||||
|
{:ok, delete(conn), identity}
|
||||||
|
else
|
||||||
|
false -> {:error, delete(conn), :email_mismatch}
|
||||||
|
{:error, reason} -> {:error, delete(conn), reason}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp connect_and_audit(user, pending) do
|
||||||
|
Repo.transact(fn ->
|
||||||
|
with {:ok, identity} <- Accounts.link_google_identity(user, identity_attrs(pending)),
|
||||||
|
{:ok, _audit} <-
|
||||||
|
Trust.audit(
|
||||||
|
user.id,
|
||||||
|
"auth_identity.connected",
|
||||||
|
"auth_identity",
|
||||||
|
identity.id,
|
||||||
|
%{"provider" => "google", "method" => "verified_local_sign_in"}
|
||||||
|
) do
|
||||||
|
{:ok, identity}
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp verify_token(token) when is_binary(token) do
|
||||||
|
with {:ok, payload} <-
|
||||||
|
Phoenix.Token.verify(WhoNeedHelpWeb.Endpoint, @token_salt, token,
|
||||||
|
max_age: @max_age_seconds
|
||||||
|
),
|
||||||
|
{:ok, pending} <- normalize(payload, value(payload, :locale)) do
|
||||||
|
{:ok, pending}
|
||||||
|
else
|
||||||
|
_invalid_or_expired -> {:error, :invalid_or_expired}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp verify_token(_token), do: {:error, :missing}
|
||||||
|
|
||||||
|
defp normalize(attrs, locale) when is_map(attrs) do
|
||||||
|
provider_uid = value(attrs, :provider_uid)
|
||||||
|
email = value(attrs, :email)
|
||||||
|
email_verified = value(attrs, :email_verified)
|
||||||
|
display_name = value(attrs, :display_name)
|
||||||
|
|
||||||
|
cond do
|
||||||
|
email_verified != true ->
|
||||||
|
{:error, :invalid}
|
||||||
|
|
||||||
|
not is_binary(provider_uid) or provider_uid == "" or byte_size(provider_uid) > 255 ->
|
||||||
|
{:error, :invalid}
|
||||||
|
|
||||||
|
not is_binary(email) or email == "" or byte_size(email) > 160 ->
|
||||||
|
{:error, :invalid}
|
||||||
|
|
||||||
|
not is_binary(display_name) or String.trim(display_name) == "" ->
|
||||||
|
{:error, :invalid}
|
||||||
|
|
||||||
|
true ->
|
||||||
|
{:ok,
|
||||||
|
%{
|
||||||
|
provider_uid: provider_uid,
|
||||||
|
email: normalized_email(email),
|
||||||
|
email_verified: true,
|
||||||
|
display_name: display_name |> String.trim() |> String.slice(0, 80),
|
||||||
|
locale: normalize_locale(locale)
|
||||||
|
}}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp normalize(_attrs, _locale), do: {:error, :invalid}
|
||||||
|
|
||||||
|
defp identity_attrs(pending) do
|
||||||
|
Map.take(pending, [:provider_uid, :email, :email_verified, :display_name])
|
||||||
|
end
|
||||||
|
|
||||||
|
defp value(attrs, key), do: Map.get(attrs, key) || Map.get(attrs, Atom.to_string(key))
|
||||||
|
|
||||||
|
defp normalized_email(email), do: email |> String.trim() |> String.downcase()
|
||||||
|
|
||||||
|
defp normalize_locale(locale) when locale in @supported_locales, do: locale
|
||||||
|
defp normalize_locale(_locale), do: "en"
|
||||||
|
end
|
||||||
|
|
@ -120,6 +120,9 @@ defmodule WhoNeedHelpWeb.Router do
|
||||||
post "/users/register", UserRegistrationController, :create
|
post "/users/register", UserRegistrationController, :create
|
||||||
post "/auth/google/login", GoogleAuthController, :start_login
|
post "/auth/google/login", GoogleAuthController, :start_login
|
||||||
post "/auth/google/register", GoogleAuthController, :start_registration
|
post "/auth/google/register", GoogleAuthController, :start_registration
|
||||||
|
get "/auth/google/complete", GoogleAuthController, :complete
|
||||||
|
post "/auth/google/complete-registration", GoogleAuthController, :complete_registration
|
||||||
|
post "/auth/google/verify-existing", GoogleAuthController, :verify_existing
|
||||||
end
|
end
|
||||||
|
|
||||||
scope "/", WhoNeedHelpWeb do
|
scope "/", WhoNeedHelpWeb do
|
||||||
|
|
|
||||||
|
|
@ -529,7 +529,7 @@ msgstr ""
|
||||||
msgid "Confirm your email and ensure your account is active before publishing."
|
msgid "Confirm your email and ensure your account is active before publishing."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help/accounts/user_notifier.ex:70
|
#: lib/who_need_help/accounts/user_notifier.ex:85
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Confirmation instructions"
|
msgid "Confirmation instructions"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -637,8 +637,8 @@ msgid "Double-blind review"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:75
|
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:75
|
||||||
#: lib/who_need_help_web/controllers/user_session_html/new.html.heex:89
|
#: lib/who_need_help_web/controllers/user_session_html/new.html.heex:99
|
||||||
#: lib/who_need_help_web/controllers/user_session_html/new.html.heex:122
|
#: lib/who_need_help_web/controllers/user_session_html/new.html.heex:132
|
||||||
#: lib/who_need_help_web/controllers/user_settings_html/edit.html.heex:15
|
#: lib/who_need_help_web/controllers/user_settings_html/edit.html.heex:15
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Email"
|
msgid "Email"
|
||||||
|
|
@ -806,12 +806,12 @@ msgstr ""
|
||||||
msgid "Hi %{email},\n\nYou can change your email by visiting the URL below:\n\n%{url}\n\nIf you didn't request this change, please ignore this."
|
msgid "Hi %{email},\n\nYou can change your email by visiting the URL below:\n\n%{url}\n\nIf you didn't request this change, please ignore this."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help/accounts/user_notifier.ex:71
|
#: lib/who_need_help/accounts/user_notifier.ex:86
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Hi %{email},\n\nYou can confirm your account by visiting the URL below:\n\n%{url}\n\nIf you didn't create an account with us, please ignore this."
|
msgid "Hi %{email},\n\nYou can confirm your account by visiting the URL below:\n\n%{url}\n\nIf you didn't create an account with us, please ignore this."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help/accounts/user_notifier.ex:57
|
#: lib/who_need_help/accounts/user_notifier.ex:72
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Hi %{email},\n\nYou can log into your account by visiting the URL below:\n\n%{url}\n\nIf you didn't request this email, please ignore this."
|
msgid "Hi %{email},\n\nYou can log into your account by visiting the URL below:\n\n%{url}\n\nIf you didn't request this email, please ignore this."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -878,7 +878,7 @@ msgstr ""
|
||||||
msgid "Identity and reputation"
|
msgid "Identity and reputation"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/user_session_controller.ex:89
|
#: lib/who_need_help_web/controllers/user_session_controller.ex:97
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "If your email is in our system, you will receive instructions for logging in shortly."
|
msgid "If your email is in our system, you will receive instructions for logging in shortly."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -915,7 +915,7 @@ msgstr ""
|
||||||
msgid "Internal note"
|
msgid "Internal note"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/user_session_controller.ex:124
|
#: lib/who_need_help_web/controllers/user_session_controller.ex:132
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Invalid email or password"
|
msgid "Invalid email or password"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -977,22 +977,22 @@ msgstr ""
|
||||||
msgid "Location:"
|
msgid "Location:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/user_session_html/new.html.heex:136
|
#: lib/who_need_help_web/controllers/user_session_html/new.html.heex:146
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Log in and stay logged in"
|
msgid "Log in and stay logged in"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help/accounts/user_notifier.ex:56
|
#: lib/who_need_help/accounts/user_notifier.ex:71
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Log in instructions"
|
msgid "Log in instructions"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/user_session_html/new.html.heex:139
|
#: lib/who_need_help_web/controllers/user_session_html/new.html.heex:149
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Log in only this time"
|
msgid "Log in only this time"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/user_session_controller.ex:117
|
#: lib/who_need_help_web/controllers/user_session_controller.ex:125
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Logged out successfully."
|
msgid "Logged out successfully."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -1323,7 +1323,7 @@ msgstr ""
|
||||||
msgid "Participant"
|
msgid "Participant"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/user_session_html/new.html.heex:130
|
#: lib/who_need_help_web/controllers/user_session_html/new.html.heex:140
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Password"
|
msgid "Password"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -1504,6 +1504,7 @@ msgstr ""
|
||||||
msgid "Rating"
|
msgid "Rating"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_html/complete.html.heex:80
|
||||||
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:43
|
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:43
|
||||||
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:90
|
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:90
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
|
|
@ -1925,7 +1926,7 @@ msgstr ""
|
||||||
msgid "The last administrator cannot demote themselves."
|
msgid "The last administrator cannot demote themselves."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/user_session_controller.ex:37
|
#: lib/who_need_help_web/controllers/user_session_controller.ex:44
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "The link is invalid or it has expired."
|
msgid "The link is invalid or it has expired."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -2046,7 +2047,8 @@ msgstr ""
|
||||||
msgid "Too many actions in the configured time window."
|
msgid "Too many actions in the configured time window."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/google_auth_controller.ex:180
|
#: lib/who_need_help_web/controllers/google_auth_controller.ex:139
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_controller.ex:309
|
||||||
#: lib/who_need_help_web/controllers/user_registration_controller.ex:49
|
#: lib/who_need_help_web/controllers/user_registration_controller.ex:49
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Too many registration attempts in the configured time window."
|
msgid "Too many registration attempts in the configured time window."
|
||||||
|
|
@ -2057,7 +2059,8 @@ msgstr ""
|
||||||
msgid "Too many requests in the configured time window."
|
msgid "Too many requests in the configured time window."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/user_session_controller.ex:102
|
#: lib/who_need_help_web/controllers/google_auth_controller.ex:189
|
||||||
|
#: lib/who_need_help_web/controllers/user_session_controller.ex:110
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Too many sign-in emails in the configured time window."
|
msgid "Too many sign-in emails in the configured time window."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -2162,7 +2165,7 @@ msgstr ""
|
||||||
msgid "User blocked. Their requests and new messages are hidden."
|
msgid "User blocked. Their requests and new messages are hidden."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/user_session_controller.ex:25
|
#: lib/who_need_help_web/controllers/user_session_controller.ex:31
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "User confirmed successfully."
|
msgid "User confirmed successfully."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -2218,9 +2221,9 @@ msgstr ""
|
||||||
msgid "Waiting for a nearby volunteer."
|
msgid "Waiting for a nearby volunteer."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/google_auth_controller.ex:137
|
#: lib/who_need_help_web/controllers/google_auth_controller.ex:266
|
||||||
#: lib/who_need_help_web/controllers/user_session_controller.ex:26
|
#: lib/who_need_help_web/controllers/user_session_controller.ex:32
|
||||||
#: lib/who_need_help_web/controllers/user_session_controller.ex:51
|
#: lib/who_need_help_web/controllers/user_session_controller.ex:58
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Welcome back!"
|
msgid "Welcome back!"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -2423,6 +2426,7 @@ msgstr ""
|
||||||
msgid "activity message"
|
msgid "activity message"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_html/complete.html.heex:85
|
||||||
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:48
|
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:48
|
||||||
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:95
|
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:95
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
|
|
@ -2737,7 +2741,7 @@ msgstr ""
|
||||||
msgid "The settings form is invalid."
|
msgid "The settings form is invalid."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/user_session_controller.ex:111
|
#: lib/who_need_help_web/controllers/user_session_controller.ex:119
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "The sign-in form is invalid."
|
msgid "The sign-in form is invalid."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -2762,7 +2766,7 @@ msgstr ""
|
||||||
msgid "This request has expired."
|
msgid "This request has expired."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/user_session_controller.ex:60
|
#: lib/who_need_help_web/controllers/user_session_controller.ex:68
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Too many sign-in attempts in the configured time window."
|
msgid "Too many sign-in attempts in the configured time window."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -2797,7 +2801,7 @@ msgstr ""
|
||||||
msgid "A Google account is connected. You can use it to sign in."
|
msgid "A Google account is connected. You can use it to sign in."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/google_auth_controller.ex:207
|
#: lib/who_need_help_web/controllers/google_auth_controller.ex:336
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "A different Google account is already connected."
|
msgid "A different Google account is already connected."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -2807,12 +2811,8 @@ msgstr ""
|
||||||
msgid "A password is not required. We will email a one-time confirmation link. You can add a password later in account settings."
|
msgid "A password is not required. We will email a one-time confirmation link. You can add a password later in account settings."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/google_auth_controller.ex:170
|
#: lib/who_need_help_web/controllers/google_auth_controller.ex:42
|
||||||
#, elixir-autogen, elixir-format
|
#: lib/who_need_help_web/controllers/google_auth_controller.ex:123
|
||||||
msgid "An account with this email already exists. Sign in by email or password, then connect Google in account settings."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/google_auth_controller.ex:37
|
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Confirm that you are 18 or older and accept the safety rules first."
|
msgid "Confirm that you are 18 or older and accept the safety rules first."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -2832,17 +2832,17 @@ msgstr ""
|
||||||
msgid "Create account and email me a link"
|
msgid "Create account and email me a link"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/user_session_html/new.html.heex:99
|
#: lib/who_need_help_web/controllers/user_session_html/new.html.heex:109
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Email me a sign-in link"
|
msgid "Email me a sign-in link"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/google_auth_controller.ex:215
|
#: lib/who_need_help_web/controllers/google_auth_controller.ex:344
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Google account connection session is invalid."
|
msgid "Google account connection session is invalid."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/google_auth_controller.ex:97
|
#: lib/who_need_help_web/controllers/google_auth_controller.ex:226
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Google did not provide a verified email address."
|
msgid "Google did not provide a verified email address."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -2852,32 +2852,34 @@ msgstr ""
|
||||||
msgid "Google sign-in"
|
msgid "Google sign-in"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/google_auth_controller.ex:197
|
#: lib/who_need_help_web/controllers/google_auth_controller.ex:326
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Google sign-in connected."
|
msgid "Google sign-in connected."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/google_auth_controller.ex:123
|
#: lib/who_need_help_web/controllers/google_auth_controller.ex:252
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Google sign-in could not be started."
|
msgid "Google sign-in could not be started."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/google_auth_controller.ex:102
|
#: lib/who_need_help_web/controllers/google_auth_controller.ex:231
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Google sign-in failed. Please try again."
|
msgid "Google sign-in failed. Please try again."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/google_auth_controller.ex:128
|
#: lib/who_need_help_web/controllers/google_auth_controller.ex:257
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Google sign-in is not configured yet."
|
msgid "Google sign-in is not configured yet."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/google_auth_controller.ex:87
|
#: lib/who_need_help_web/controllers/google_auth_controller.ex:97
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_controller.ex:216
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_controller.ex:399
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Google sign-in session expired. Please start again."
|
msgid "Google sign-in session expired. Please start again."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/google_auth_controller.ex:91
|
#: lib/who_need_help_web/controllers/google_auth_controller.ex:220
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Google sign-in session is invalid."
|
msgid "Google sign-in session is invalid."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -2894,52 +2896,44 @@ msgstr ""
|
||||||
msgid "Sending link..."
|
msgid "Sending link..."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/user_session_html/new.html.heex:74
|
|
||||||
#, elixir-autogen, elixir-format
|
|
||||||
msgid "Sign in with Google"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:51
|
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:51
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Sign up with Google"
|
msgid "Sign up with Google"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/google_auth_controller.ex:202
|
#: lib/who_need_help_web/controllers/google_auth_controller.ex:331
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "That Google account belongs to another local account."
|
msgid "That Google account belongs to another local account."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/google_auth_controller.ex:45
|
#: lib/who_need_help_web/controllers/google_auth_controller.ex:50
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_controller.ex:164
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "The Google registration form is invalid."
|
msgid "The Google registration form is invalid."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/google_auth_controller.ex:260
|
#: lib/who_need_help_web/controllers/google_auth_controller.ex:405
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "This Google account cannot be used right now."
|
msgid "This Google account cannot be used right now."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/google_auth_controller.ex:144
|
#: lib/who_need_help_web/controllers/user_session_html/new.html.heex:119
|
||||||
#, elixir-autogen, elixir-format
|
|
||||||
msgid "This Google account is not connected yet. Create an account or sign in by email and connect Google in account settings."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/user_session_html/new.html.heex:109
|
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "This works only if you previously added a password in account settings."
|
msgid "This works only if you previously added a password in account settings."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/user_session_html/new.html.heex:105
|
#: lib/who_need_help_web/controllers/user_session_html/new.html.heex:115
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Use a password instead"
|
msgid "Use a password instead"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/user_session_html/new.html.heex:96
|
#: lib/who_need_help_web/controllers/user_session_html/new.html.heex:106
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "We will send a one-time sign-in link. No password is required."
|
msgid "We will send a one-time sign-in link. No password is required."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/google_auth_controller.ex:163
|
#: lib/who_need_help_web/controllers/google_auth_controller.ex:116
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_controller.ex:288
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Your account was created with Google."
|
msgid "Your account was created with Google."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -2964,12 +2958,12 @@ msgstr ""
|
||||||
msgid "Disconnect Google sign-in from this account?"
|
msgid "Disconnect Google sign-in from this account?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/google_auth_controller.ex:60
|
#: lib/who_need_help_web/controllers/google_auth_controller.ex:65
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Google sign-in disconnected."
|
msgid "Google sign-in disconnected."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/google_auth_controller.ex:65
|
#: lib/who_need_help_web/controllers/google_auth_controller.ex:70
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "No Google account is connected."
|
msgid "No Google account is connected."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -3603,6 +3597,7 @@ msgstr ""
|
||||||
msgid "Please delete my account and associated personal data."
|
msgid "Please delete my account and associated personal data."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_html/complete.html.heex:76
|
||||||
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:39
|
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:39
|
||||||
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:101
|
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:101
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
|
|
@ -3614,12 +3609,14 @@ msgstr ""
|
||||||
msgid "Privacy"
|
msgid "Privacy"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_html/complete.html.heex:82
|
||||||
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:45
|
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:45
|
||||||
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:92
|
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:92
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Privacy Policy"
|
msgid "Privacy Policy"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_html/complete.html.heex:84
|
||||||
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:47
|
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:47
|
||||||
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:94
|
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:94
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
|
|
@ -3627,12 +3624,14 @@ msgid "Safety Rules"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/who_need_help_web/components/layouts.ex:149
|
#: lib/who_need_help_web/components/layouts.ex:149
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_html/complete.html.heex:81
|
||||||
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:44
|
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:44
|
||||||
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:91
|
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:91
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Terms"
|
msgid "Terms"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_html/complete.html.heex:83
|
||||||
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:46
|
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:46
|
||||||
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:93
|
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:93
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
|
|
@ -3956,3 +3955,111 @@ msgstr ""
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "You stay in control of the match"
|
msgid "You stay in control of the match"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_html/complete.html.heex:52
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "After this confirmation, future Google sign-ins will take one click."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_html/complete.html.heex:99
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Cancel and use another sign-in method"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_html/complete.html.heex:35
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Confirm access once so nobody can attach Google to your account using only a matching email address."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_html/complete.html.heex:5
|
||||||
|
#: lib/who_need_help_web/controllers/user_session_html/new.html.heex:74
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Continue with Google"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_html/complete.html.heex:91
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Create account and continue"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_html/complete.html.heex:58
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Create your Who Need Help account"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_html/complete.html.heex:89
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Creating account..."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_html/complete.html.heex:43
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Email me a verification link"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/controllers/user_session_controller.ex:158
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Google sign-in connected. You can use it next time."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_html/complete.html.heex:7
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Google verified your identity. Finish this one-time step to continue."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_html/complete.html.heex:60
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "No password is required. Google will be connected as your sign-in method."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_html/complete.html.heex:42
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Sending..."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/controllers/user_session_html/new.html.heex:88
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Sign in to %{email} once to connect Google. You can use the email link or your existing password."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_html/complete.html.heex:33
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "This email already has an account"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_controller.ex:131
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_controller.ex:153
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_controller.ex:297
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "This email already has an account. Confirm it once to connect Google."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_html/complete.html.heex:48
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Use my password instead"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_html/complete.html.heex:25
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Verified"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_controller.ex:178
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "We sent a verification link to %{email}. Open it to finish connecting Google."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/controllers/user_session_controller.ex:171
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "You are signed in, but Google could not be connected. Try again in account settings."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/who_need_help/accounts/user_notifier.ex:57
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Confirm Google sign-in"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/who_need_help/accounts/user_notifier.ex:58
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Hi %{email},\n\nUse the secure link below to sign in and connect Google to your Who Need Help account:\n\n%{url}\n\nIf you did not request this, ignore this email. Google will not be connected."
|
||||||
|
msgstr ""
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -550,7 +550,7 @@ msgstr ""
|
||||||
"Перед публикацией подтвердите электронную почту и убедитесь, что учётная "
|
"Перед публикацией подтвердите электронную почту и убедитесь, что учётная "
|
||||||
"запись активна."
|
"запись активна."
|
||||||
|
|
||||||
#: lib/who_need_help/accounts/user_notifier.ex:70
|
#: lib/who_need_help/accounts/user_notifier.ex:85
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Confirmation instructions"
|
msgid "Confirmation instructions"
|
||||||
msgstr "Инструкции по подтверждению"
|
msgstr "Инструкции по подтверждению"
|
||||||
|
|
@ -665,8 +665,8 @@ msgid "Double-blind review"
|
||||||
msgstr "Двусторонний скрытый отзыв"
|
msgstr "Двусторонний скрытый отзыв"
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:75
|
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:75
|
||||||
#: lib/who_need_help_web/controllers/user_session_html/new.html.heex:89
|
#: lib/who_need_help_web/controllers/user_session_html/new.html.heex:99
|
||||||
#: lib/who_need_help_web/controllers/user_session_html/new.html.heex:122
|
#: lib/who_need_help_web/controllers/user_session_html/new.html.heex:132
|
||||||
#: lib/who_need_help_web/controllers/user_settings_html/edit.html.heex:15
|
#: lib/who_need_help_web/controllers/user_settings_html/edit.html.heex:15
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Email"
|
msgid "Email"
|
||||||
|
|
@ -852,7 +852,7 @@ msgstr ""
|
||||||
"\n"
|
"\n"
|
||||||
"Если вы не запрашивали это изменение, просто проигнорируйте письмо."
|
"Если вы не запрашивали это изменение, просто проигнорируйте письмо."
|
||||||
|
|
||||||
#: lib/who_need_help/accounts/user_notifier.ex:71
|
#: lib/who_need_help/accounts/user_notifier.ex:86
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Hi %{email},\n\nYou can confirm your account by visiting the URL below:\n\n%{url}\n\nIf you didn't create an account with us, please ignore this."
|
msgid "Hi %{email},\n\nYou can confirm your account by visiting the URL below:\n\n%{url}\n\nIf you didn't create an account with us, please ignore this."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -864,7 +864,7 @@ msgstr ""
|
||||||
"\n"
|
"\n"
|
||||||
"Если вы не создавали у нас учётную запись, просто проигнорируйте письмо."
|
"Если вы не создавали у нас учётную запись, просто проигнорируйте письмо."
|
||||||
|
|
||||||
#: lib/who_need_help/accounts/user_notifier.ex:57
|
#: lib/who_need_help/accounts/user_notifier.ex:72
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Hi %{email},\n\nYou can log into your account by visiting the URL below:\n\n%{url}\n\nIf you didn't request this email, please ignore this."
|
msgid "Hi %{email},\n\nYou can log into your account by visiting the URL below:\n\n%{url}\n\nIf you didn't request this email, please ignore this."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -949,7 +949,7 @@ msgstr ""
|
||||||
msgid "Identity and reputation"
|
msgid "Identity and reputation"
|
||||||
msgstr "Личность и репутация"
|
msgstr "Личность и репутация"
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/user_session_controller.ex:89
|
#: lib/who_need_help_web/controllers/user_session_controller.ex:97
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "If your email is in our system, you will receive instructions for logging in shortly."
|
msgid "If your email is in our system, you will receive instructions for logging in shortly."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -991,7 +991,7 @@ msgstr "Язык интерфейса"
|
||||||
msgid "Internal note"
|
msgid "Internal note"
|
||||||
msgstr "Внутренняя заметка"
|
msgstr "Внутренняя заметка"
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/user_session_controller.ex:124
|
#: lib/who_need_help_web/controllers/user_session_controller.ex:132
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Invalid email or password"
|
msgid "Invalid email or password"
|
||||||
msgstr "Неверная электронная почта или пароль"
|
msgstr "Неверная электронная почта или пароль"
|
||||||
|
|
@ -1055,22 +1055,22 @@ msgstr "Люди с подтверждением геопозицией"
|
||||||
msgid "Location:"
|
msgid "Location:"
|
||||||
msgstr "Геопозиция:"
|
msgstr "Геопозиция:"
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/user_session_html/new.html.heex:136
|
#: lib/who_need_help_web/controllers/user_session_html/new.html.heex:146
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Log in and stay logged in"
|
msgid "Log in and stay logged in"
|
||||||
msgstr "Войти и оставаться в системе"
|
msgstr "Войти и оставаться в системе"
|
||||||
|
|
||||||
#: lib/who_need_help/accounts/user_notifier.ex:56
|
#: lib/who_need_help/accounts/user_notifier.ex:71
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Log in instructions"
|
msgid "Log in instructions"
|
||||||
msgstr "Инструкции для входа"
|
msgstr "Инструкции для входа"
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/user_session_html/new.html.heex:139
|
#: lib/who_need_help_web/controllers/user_session_html/new.html.heex:149
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Log in only this time"
|
msgid "Log in only this time"
|
||||||
msgstr "Войти только сейчас"
|
msgstr "Войти только сейчас"
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/user_session_controller.ex:117
|
#: lib/who_need_help_web/controllers/user_session_controller.ex:125
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Logged out successfully."
|
msgid "Logged out successfully."
|
||||||
msgstr "Вы успешно вышли."
|
msgstr "Вы успешно вышли."
|
||||||
|
|
@ -1422,7 +1422,7 @@ msgstr "Родительская категория (необязательно)
|
||||||
msgid "Participant"
|
msgid "Participant"
|
||||||
msgstr "Участник"
|
msgstr "Участник"
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/user_session_html/new.html.heex:130
|
#: lib/who_need_help_web/controllers/user_session_html/new.html.heex:140
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Password"
|
msgid "Password"
|
||||||
msgstr "Пароль"
|
msgstr "Пароль"
|
||||||
|
|
@ -1620,6 +1620,7 @@ msgstr ""
|
||||||
msgid "Rating"
|
msgid "Rating"
|
||||||
msgstr "Оценка"
|
msgstr "Оценка"
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_html/complete.html.heex:80
|
||||||
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:43
|
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:43
|
||||||
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:90
|
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:90
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
|
|
@ -2051,7 +2052,7 @@ msgstr "Браузеру не удалось передать вашу геоп
|
||||||
msgid "The last administrator cannot demote themselves."
|
msgid "The last administrator cannot demote themselves."
|
||||||
msgstr "Последний администратор не может понизить собственную роль."
|
msgstr "Последний администратор не может понизить собственную роль."
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/user_session_controller.ex:37
|
#: lib/who_need_help_web/controllers/user_session_controller.ex:44
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "The link is invalid or it has expired."
|
msgid "The link is invalid or it has expired."
|
||||||
msgstr "Ссылка недействительна или просрочена."
|
msgstr "Ссылка недействительна или просрочена."
|
||||||
|
|
@ -2182,7 +2183,8 @@ msgstr "Сегодня"
|
||||||
msgid "Too many actions in the configured time window."
|
msgid "Too many actions in the configured time window."
|
||||||
msgstr "Слишком много действий за настроенный промежуток времени."
|
msgstr "Слишком много действий за настроенный промежуток времени."
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/google_auth_controller.ex:180
|
#: lib/who_need_help_web/controllers/google_auth_controller.ex:139
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_controller.ex:309
|
||||||
#: lib/who_need_help_web/controllers/user_registration_controller.ex:49
|
#: lib/who_need_help_web/controllers/user_registration_controller.ex:49
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Too many registration attempts in the configured time window."
|
msgid "Too many registration attempts in the configured time window."
|
||||||
|
|
@ -2193,7 +2195,8 @@ msgstr "Слишком много попыток регистрации за н
|
||||||
msgid "Too many requests in the configured time window."
|
msgid "Too many requests in the configured time window."
|
||||||
msgstr "Слишком много запросов за настроенный промежуток времени."
|
msgstr "Слишком много запросов за настроенный промежуток времени."
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/user_session_controller.ex:102
|
#: lib/who_need_help_web/controllers/google_auth_controller.ex:189
|
||||||
|
#: lib/who_need_help_web/controllers/user_session_controller.ex:110
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Too many sign-in emails in the configured time window."
|
msgid "Too many sign-in emails in the configured time window."
|
||||||
msgstr "Слишком много писем для входа за настроенный промежуток времени."
|
msgstr "Слишком много писем для входа за настроенный промежуток времени."
|
||||||
|
|
@ -2303,7 +2306,7 @@ msgstr "Пользователь"
|
||||||
msgid "User blocked. Their requests and new messages are hidden."
|
msgid "User blocked. Their requests and new messages are hidden."
|
||||||
msgstr "Пользователь заблокирован. Его заявки и новые сообщения скрыты."
|
msgstr "Пользователь заблокирован. Его заявки и новые сообщения скрыты."
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/user_session_controller.ex:25
|
#: lib/who_need_help_web/controllers/user_session_controller.ex:31
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "User confirmed successfully."
|
msgid "User confirmed successfully."
|
||||||
msgstr "Пользователь успешно подтверждён."
|
msgstr "Пользователь успешно подтверждён."
|
||||||
|
|
@ -2359,9 +2362,9 @@ msgstr "Открытые отзывы"
|
||||||
msgid "Waiting for a nearby volunteer."
|
msgid "Waiting for a nearby volunteer."
|
||||||
msgstr "Ожидаем помощника поблизости."
|
msgstr "Ожидаем помощника поблизости."
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/google_auth_controller.ex:137
|
#: lib/who_need_help_web/controllers/google_auth_controller.ex:266
|
||||||
#: lib/who_need_help_web/controllers/user_session_controller.ex:26
|
#: lib/who_need_help_web/controllers/user_session_controller.ex:32
|
||||||
#: lib/who_need_help_web/controllers/user_session_controller.ex:51
|
#: lib/who_need_help_web/controllers/user_session_controller.ex:58
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Welcome back!"
|
msgid "Welcome back!"
|
||||||
msgstr "С возвращением!"
|
msgstr "С возвращением!"
|
||||||
|
|
@ -2580,6 +2583,7 @@ msgstr "активность"
|
||||||
msgid "activity message"
|
msgid "activity message"
|
||||||
msgstr "сообщение активности"
|
msgstr "сообщение активности"
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_html/complete.html.heex:85
|
||||||
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:48
|
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:48
|
||||||
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:95
|
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:95
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
|
|
@ -2894,7 +2898,7 @@ msgstr "Выбранная запись больше недоступна."
|
||||||
msgid "The settings form is invalid."
|
msgid "The settings form is invalid."
|
||||||
msgstr "Форма настроек заполнена неверно."
|
msgstr "Форма настроек заполнена неверно."
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/user_session_controller.ex:111
|
#: lib/who_need_help_web/controllers/user_session_controller.ex:119
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "The sign-in form is invalid."
|
msgid "The sign-in form is invalid."
|
||||||
msgstr "Форма входа заполнена неверно."
|
msgstr "Форма входа заполнена неверно."
|
||||||
|
|
@ -2919,7 +2923,7 @@ msgstr "Это предложение больше недоступно."
|
||||||
msgid "This request has expired."
|
msgid "This request has expired."
|
||||||
msgstr "Срок действия этой заявки истёк."
|
msgstr "Срок действия этой заявки истёк."
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/user_session_controller.ex:60
|
#: lib/who_need_help_web/controllers/user_session_controller.ex:68
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Too many sign-in attempts in the configured time window."
|
msgid "Too many sign-in attempts in the configured time window."
|
||||||
msgstr "Слишком много попыток входа за настроенный промежуток времени."
|
msgstr "Слишком много попыток входа за настроенный промежуток времени."
|
||||||
|
|
@ -2954,7 +2958,7 @@ msgstr "Слишком много запросов на смену email за н
|
||||||
msgid "A Google account is connected. You can use it to sign in."
|
msgid "A Google account is connected. You can use it to sign in."
|
||||||
msgstr "Аккаунт Google подключён. Теперь с его помощью можно входить."
|
msgstr "Аккаунт Google подключён. Теперь с его помощью можно входить."
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/google_auth_controller.ex:207
|
#: lib/who_need_help_web/controllers/google_auth_controller.ex:336
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "A different Google account is already connected."
|
msgid "A different Google account is already connected."
|
||||||
msgstr "Уже подключён другой аккаунт Google."
|
msgstr "Уже подключён другой аккаунт Google."
|
||||||
|
|
@ -2964,12 +2968,8 @@ msgstr "Уже подключён другой аккаунт Google."
|
||||||
msgid "A password is not required. We will email a one-time confirmation link. You can add a password later in account settings."
|
msgid "A password is not required. We will email a one-time confirmation link. You can add a password later in account settings."
|
||||||
msgstr "Пароль не обязателен. Мы отправим на email одноразовую ссылку для подтверждения. Пароль можно добавить позже в настройках аккаунта."
|
msgstr "Пароль не обязателен. Мы отправим на email одноразовую ссылку для подтверждения. Пароль можно добавить позже в настройках аккаунта."
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/google_auth_controller.ex:170
|
#: lib/who_need_help_web/controllers/google_auth_controller.ex:42
|
||||||
#, elixir-autogen, elixir-format
|
#: lib/who_need_help_web/controllers/google_auth_controller.ex:123
|
||||||
msgid "An account with this email already exists. Sign in by email or password, then connect Google in account settings."
|
|
||||||
msgstr "Учётная запись с таким email уже существует. Войдите по email или паролю, затем подключите Google в настройках аккаунта."
|
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/google_auth_controller.ex:37
|
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Confirm that you are 18 or older and accept the safety rules first."
|
msgid "Confirm that you are 18 or older and accept the safety rules first."
|
||||||
msgstr "Сначала подтвердите, что вам уже исполнилось 18 лет, и примите правила безопасности."
|
msgstr "Сначала подтвердите, что вам уже исполнилось 18 лет, и примите правила безопасности."
|
||||||
|
|
@ -2989,17 +2989,17 @@ msgstr "Подключайте Google только после входа зде
|
||||||
msgid "Create account and email me a link"
|
msgid "Create account and email me a link"
|
||||||
msgstr "Создать аккаунт и отправить ссылку на email"
|
msgstr "Создать аккаунт и отправить ссылку на email"
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/user_session_html/new.html.heex:99
|
#: lib/who_need_help_web/controllers/user_session_html/new.html.heex:109
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Email me a sign-in link"
|
msgid "Email me a sign-in link"
|
||||||
msgstr "Отправить ссылку для входа на email"
|
msgstr "Отправить ссылку для входа на email"
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/google_auth_controller.ex:215
|
#: lib/who_need_help_web/controllers/google_auth_controller.ex:344
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Google account connection session is invalid."
|
msgid "Google account connection session is invalid."
|
||||||
msgstr "Сессия подключения аккаунта Google недействительна."
|
msgstr "Сессия подключения аккаунта Google недействительна."
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/google_auth_controller.ex:97
|
#: lib/who_need_help_web/controllers/google_auth_controller.ex:226
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Google did not provide a verified email address."
|
msgid "Google did not provide a verified email address."
|
||||||
msgstr "Google не предоставил подтверждённый адрес email."
|
msgstr "Google не предоставил подтверждённый адрес email."
|
||||||
|
|
@ -3009,32 +3009,34 @@ msgstr "Google не предоставил подтверждённый адре
|
||||||
msgid "Google sign-in"
|
msgid "Google sign-in"
|
||||||
msgstr "Вход через Google"
|
msgstr "Вход через Google"
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/google_auth_controller.ex:197
|
#: lib/who_need_help_web/controllers/google_auth_controller.ex:326
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Google sign-in connected."
|
msgid "Google sign-in connected."
|
||||||
msgstr "Вход через Google подключён."
|
msgstr "Вход через Google подключён."
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/google_auth_controller.ex:123
|
#: lib/who_need_help_web/controllers/google_auth_controller.ex:252
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Google sign-in could not be started."
|
msgid "Google sign-in could not be started."
|
||||||
msgstr "Не удалось начать вход через Google."
|
msgstr "Не удалось начать вход через Google."
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/google_auth_controller.ex:102
|
#: lib/who_need_help_web/controllers/google_auth_controller.ex:231
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Google sign-in failed. Please try again."
|
msgid "Google sign-in failed. Please try again."
|
||||||
msgstr "Не удалось войти через Google. Попробуйте ещё раз."
|
msgstr "Не удалось войти через Google. Попробуйте ещё раз."
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/google_auth_controller.ex:128
|
#: lib/who_need_help_web/controllers/google_auth_controller.ex:257
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Google sign-in is not configured yet."
|
msgid "Google sign-in is not configured yet."
|
||||||
msgstr "Вход через Google пока не настроен."
|
msgstr "Вход через Google пока не настроен."
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/google_auth_controller.ex:87
|
#: lib/who_need_help_web/controllers/google_auth_controller.ex:97
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_controller.ex:216
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_controller.ex:399
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Google sign-in session expired. Please start again."
|
msgid "Google sign-in session expired. Please start again."
|
||||||
msgstr "Сессия входа через Google истекла. Начните заново."
|
msgstr "Сессия входа через Google истекла. Начните заново."
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/google_auth_controller.ex:91
|
#: lib/who_need_help_web/controllers/google_auth_controller.ex:220
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Google sign-in session is invalid."
|
msgid "Google sign-in session is invalid."
|
||||||
msgstr "Сессия входа через Google недействительна."
|
msgstr "Сессия входа через Google недействительна."
|
||||||
|
|
@ -3051,52 +3053,44 @@ msgstr "Вход через Google станет доступен после на
|
||||||
msgid "Sending link..."
|
msgid "Sending link..."
|
||||||
msgstr "Отправляем ссылку..."
|
msgstr "Отправляем ссылку..."
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/user_session_html/new.html.heex:74
|
|
||||||
#, elixir-autogen, elixir-format
|
|
||||||
msgid "Sign in with Google"
|
|
||||||
msgstr "Войти через Google"
|
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:51
|
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:51
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Sign up with Google"
|
msgid "Sign up with Google"
|
||||||
msgstr "Зарегистрироваться через Google"
|
msgstr "Зарегистрироваться через Google"
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/google_auth_controller.ex:202
|
#: lib/who_need_help_web/controllers/google_auth_controller.ex:331
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "That Google account belongs to another local account."
|
msgid "That Google account belongs to another local account."
|
||||||
msgstr "Этот аккаунт Google принадлежит другой локальной учётной записи."
|
msgstr "Этот аккаунт Google принадлежит другой локальной учётной записи."
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/google_auth_controller.ex:45
|
#: lib/who_need_help_web/controllers/google_auth_controller.ex:50
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_controller.ex:164
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "The Google registration form is invalid."
|
msgid "The Google registration form is invalid."
|
||||||
msgstr "Форма регистрации через Google заполнена неверно."
|
msgstr "Форма регистрации через Google заполнена неверно."
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/google_auth_controller.ex:260
|
#: lib/who_need_help_web/controllers/google_auth_controller.ex:405
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "This Google account cannot be used right now."
|
msgid "This Google account cannot be used right now."
|
||||||
msgstr "Этот аккаунт Google сейчас нельзя использовать."
|
msgstr "Этот аккаунт Google сейчас нельзя использовать."
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/google_auth_controller.ex:144
|
#: lib/who_need_help_web/controllers/user_session_html/new.html.heex:119
|
||||||
#, elixir-autogen, elixir-format
|
|
||||||
msgid "This Google account is not connected yet. Create an account or sign in by email and connect Google in account settings."
|
|
||||||
msgstr "Этот аккаунт Google ещё не подключён. Создайте учётную запись или войдите по email и подключите Google в настройках аккаунта."
|
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/user_session_html/new.html.heex:109
|
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "This works only if you previously added a password in account settings."
|
msgid "This works only if you previously added a password in account settings."
|
||||||
msgstr "Это работает, только если вы ранее добавили пароль в настройках аккаунта."
|
msgstr "Это работает, только если вы ранее добавили пароль в настройках аккаунта."
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/user_session_html/new.html.heex:105
|
#: lib/who_need_help_web/controllers/user_session_html/new.html.heex:115
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Use a password instead"
|
msgid "Use a password instead"
|
||||||
msgstr "Войти по паролю"
|
msgstr "Войти по паролю"
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/user_session_html/new.html.heex:96
|
#: lib/who_need_help_web/controllers/user_session_html/new.html.heex:106
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "We will send a one-time sign-in link. No password is required."
|
msgid "We will send a one-time sign-in link. No password is required."
|
||||||
msgstr "Мы отправим одноразовую ссылку для входа. Пароль не требуется."
|
msgstr "Мы отправим одноразовую ссылку для входа. Пароль не требуется."
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/google_auth_controller.ex:163
|
#: lib/who_need_help_web/controllers/google_auth_controller.ex:116
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_controller.ex:288
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Your account was created with Google."
|
msgid "Your account was created with Google."
|
||||||
msgstr "Ваша учётная запись создана через Google."
|
msgstr "Ваша учётная запись создана через Google."
|
||||||
|
|
@ -3121,12 +3115,12 @@ msgstr "Отключить Google"
|
||||||
msgid "Disconnect Google sign-in from this account?"
|
msgid "Disconnect Google sign-in from this account?"
|
||||||
msgstr "Отключить вход через Google для этой учётной записи?"
|
msgstr "Отключить вход через Google для этой учётной записи?"
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/google_auth_controller.ex:60
|
#: lib/who_need_help_web/controllers/google_auth_controller.ex:65
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Google sign-in disconnected."
|
msgid "Google sign-in disconnected."
|
||||||
msgstr "Вход через Google отключён."
|
msgstr "Вход через Google отключён."
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/google_auth_controller.ex:65
|
#: lib/who_need_help_web/controllers/google_auth_controller.ex:70
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "No Google account is connected."
|
msgid "No Google account is connected."
|
||||||
msgstr "Аккаунт Google не подключён."
|
msgstr "Аккаунт Google не подключён."
|
||||||
|
|
@ -3760,6 +3754,7 @@ msgstr "Удалить мой аккаунт Who Need Help"
|
||||||
msgid "Please delete my account and associated personal data."
|
msgid "Please delete my account and associated personal data."
|
||||||
msgstr "Пожалуйста, удалите мой аккаунт и связанные персональные данные."
|
msgstr "Пожалуйста, удалите мой аккаунт и связанные персональные данные."
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_html/complete.html.heex:76
|
||||||
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:39
|
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:39
|
||||||
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:101
|
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:101
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
|
|
@ -3771,12 +3766,14 @@ msgstr "Мне 18 лет или больше, и я принимаю Услов
|
||||||
msgid "Privacy"
|
msgid "Privacy"
|
||||||
msgstr "Конфиденциальность"
|
msgstr "Конфиденциальность"
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_html/complete.html.heex:82
|
||||||
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:45
|
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:45
|
||||||
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:92
|
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:92
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Privacy Policy"
|
msgid "Privacy Policy"
|
||||||
msgstr "Политика конфиденциальности"
|
msgstr "Политика конфиденциальности"
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_html/complete.html.heex:84
|
||||||
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:47
|
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:47
|
||||||
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:94
|
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:94
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
|
|
@ -3784,12 +3781,14 @@ msgid "Safety Rules"
|
||||||
msgstr "Правила безопасности"
|
msgstr "Правила безопасности"
|
||||||
|
|
||||||
#: lib/who_need_help_web/components/layouts.ex:149
|
#: lib/who_need_help_web/components/layouts.ex:149
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_html/complete.html.heex:81
|
||||||
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:44
|
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:44
|
||||||
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:91
|
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:91
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Terms"
|
msgid "Terms"
|
||||||
msgstr "Условия"
|
msgstr "Условия"
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_html/complete.html.heex:83
|
||||||
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:46
|
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:46
|
||||||
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:93
|
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:93
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
|
|
@ -4113,3 +4112,111 @@ msgstr "Вы сами выбираете видимость. Точные тек
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "You stay in control of the match"
|
msgid "You stay in control of the match"
|
||||||
msgstr "Вы контролируете взаимодействие"
|
msgstr "Вы контролируете взаимодействие"
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_html/complete.html.heex:52
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "After this confirmation, future Google sign-ins will take one click."
|
||||||
|
msgstr "После этого подтверждения дальнейший вход через Google будет выполняться одним нажатием."
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_html/complete.html.heex:99
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Cancel and use another sign-in method"
|
||||||
|
msgstr "Отменить и выбрать другой способ входа"
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_html/complete.html.heex:35
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Confirm access once so nobody can attach Google to your account using only a matching email address."
|
||||||
|
msgstr "Один раз подтвердите доступ, чтобы никто не смог привязать Google к вашему аккаунту лишь по совпадающему email."
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_html/complete.html.heex:5
|
||||||
|
#: lib/who_need_help_web/controllers/user_session_html/new.html.heex:74
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Continue with Google"
|
||||||
|
msgstr "Продолжить с Google"
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_html/complete.html.heex:91
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Create account and continue"
|
||||||
|
msgstr "Создать аккаунт и продолжить"
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_html/complete.html.heex:58
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Create your Who Need Help account"
|
||||||
|
msgstr "Создайте аккаунт Who Need Help"
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_html/complete.html.heex:89
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Creating account..."
|
||||||
|
msgstr "Создаём аккаунт..."
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_html/complete.html.heex:43
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Email me a verification link"
|
||||||
|
msgstr "Отправить ссылку для подтверждения на email"
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/controllers/user_session_controller.ex:158
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Google sign-in connected. You can use it next time."
|
||||||
|
msgstr "Вход через Google подключён. В следующий раз можно использовать его."
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_html/complete.html.heex:7
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Google verified your identity. Finish this one-time step to continue."
|
||||||
|
msgstr "Google подтвердил вашу личность. Выполните этот разовый шаг, чтобы продолжить."
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_html/complete.html.heex:60
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "No password is required. Google will be connected as your sign-in method."
|
||||||
|
msgstr "Пароль не нужен. Google будет подключён как способ входа."
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_html/complete.html.heex:42
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Sending..."
|
||||||
|
msgstr "Отправляем..."
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/controllers/user_session_html/new.html.heex:88
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Sign in to %{email} once to connect Google. You can use the email link or your existing password."
|
||||||
|
msgstr "Один раз войдите в %{email}, чтобы подключить Google. Можно использовать ссылку из письма или существующий пароль."
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_html/complete.html.heex:33
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "This email already has an account"
|
||||||
|
msgstr "Для этого email уже есть аккаунт"
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_controller.ex:131
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_controller.ex:153
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_controller.ex:297
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "This email already has an account. Confirm it once to connect Google."
|
||||||
|
msgstr "Для этого email уже есть аккаунт. Один раз подтвердите его, чтобы подключить Google."
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_html/complete.html.heex:48
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Use my password instead"
|
||||||
|
msgstr "Использовать пароль"
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_html/complete.html.heex:25
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Verified"
|
||||||
|
msgstr "Подтверждено"
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_controller.ex:178
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "We sent a verification link to %{email}. Open it to finish connecting Google."
|
||||||
|
msgstr "Мы отправили ссылку для подтверждения на %{email}. Откройте её, чтобы завершить подключение Google."
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/controllers/user_session_controller.ex:171
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "You are signed in, but Google could not be connected. Try again in account settings."
|
||||||
|
msgstr "Вы вошли, но подключить Google не удалось. Повторите попытку в настройках аккаунта."
|
||||||
|
|
||||||
|
#: lib/who_need_help/accounts/user_notifier.ex:57
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Confirm Google sign-in"
|
||||||
|
msgstr "Подтвердите вход через Google"
|
||||||
|
|
||||||
|
#: lib/who_need_help/accounts/user_notifier.ex:58
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Hi %{email},\n\nUse the secure link below to sign in and connect Google to your Who Need Help account:\n\n%{url}\n\nIf you did not request this, ignore this email. Google will not be connected."
|
||||||
|
msgstr "Здравствуйте, %{email}!\n\nПерейдите по защищённой ссылке ниже, чтобы войти и подключить Google к аккаунту Who Need Help:\n\n%{url}\n\nЕсли вы не запрашивали это действие, проигнорируйте письмо. Google не будет подключён."
|
||||||
|
|
|
||||||
|
|
@ -551,7 +551,7 @@ msgstr ""
|
||||||
"Перед публікацією підтвердьте електронну пошту й переконайтеся, що обліковий"
|
"Перед публікацією підтвердьте електронну пошту й переконайтеся, що обліковий"
|
||||||
" запис активний."
|
" запис активний."
|
||||||
|
|
||||||
#: lib/who_need_help/accounts/user_notifier.ex:70
|
#: lib/who_need_help/accounts/user_notifier.ex:85
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Confirmation instructions"
|
msgid "Confirmation instructions"
|
||||||
msgstr "Інструкції для підтвердження"
|
msgstr "Інструкції для підтвердження"
|
||||||
|
|
@ -665,8 +665,8 @@ msgid "Double-blind review"
|
||||||
msgstr "Двосторонній прихований відгук"
|
msgstr "Двосторонній прихований відгук"
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:75
|
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:75
|
||||||
#: lib/who_need_help_web/controllers/user_session_html/new.html.heex:89
|
#: lib/who_need_help_web/controllers/user_session_html/new.html.heex:99
|
||||||
#: lib/who_need_help_web/controllers/user_session_html/new.html.heex:122
|
#: lib/who_need_help_web/controllers/user_session_html/new.html.heex:132
|
||||||
#: lib/who_need_help_web/controllers/user_settings_html/edit.html.heex:15
|
#: lib/who_need_help_web/controllers/user_settings_html/edit.html.heex:15
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Email"
|
msgid "Email"
|
||||||
|
|
@ -851,7 +851,7 @@ msgstr ""
|
||||||
"\n"
|
"\n"
|
||||||
"Якщо ви не запитували цю зміну, просто проігноруйте лист."
|
"Якщо ви не запитували цю зміну, просто проігноруйте лист."
|
||||||
|
|
||||||
#: lib/who_need_help/accounts/user_notifier.ex:71
|
#: lib/who_need_help/accounts/user_notifier.ex:86
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Hi %{email},\n\nYou can confirm your account by visiting the URL below:\n\n%{url}\n\nIf you didn't create an account with us, please ignore this."
|
msgid "Hi %{email},\n\nYou can confirm your account by visiting the URL below:\n\n%{url}\n\nIf you didn't create an account with us, please ignore this."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -863,7 +863,7 @@ msgstr ""
|
||||||
"\n"
|
"\n"
|
||||||
"Якщо ви не створювали в нас обліковий запис, просто проігноруйте лист."
|
"Якщо ви не створювали в нас обліковий запис, просто проігноруйте лист."
|
||||||
|
|
||||||
#: lib/who_need_help/accounts/user_notifier.ex:57
|
#: lib/who_need_help/accounts/user_notifier.ex:72
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Hi %{email},\n\nYou can log into your account by visiting the URL below:\n\n%{url}\n\nIf you didn't request this email, please ignore this."
|
msgid "Hi %{email},\n\nYou can log into your account by visiting the URL below:\n\n%{url}\n\nIf you didn't request this email, please ignore this."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -946,7 +946,7 @@ msgstr ""
|
||||||
msgid "Identity and reputation"
|
msgid "Identity and reputation"
|
||||||
msgstr "Особа й репутація"
|
msgstr "Особа й репутація"
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/user_session_controller.ex:89
|
#: lib/who_need_help_web/controllers/user_session_controller.ex:97
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "If your email is in our system, you will receive instructions for logging in shortly."
|
msgid "If your email is in our system, you will receive instructions for logging in shortly."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
@ -988,7 +988,7 @@ msgstr "Мова інтерфейсу"
|
||||||
msgid "Internal note"
|
msgid "Internal note"
|
||||||
msgstr "Внутрішня нотатка"
|
msgstr "Внутрішня нотатка"
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/user_session_controller.ex:124
|
#: lib/who_need_help_web/controllers/user_session_controller.ex:132
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Invalid email or password"
|
msgid "Invalid email or password"
|
||||||
msgstr "Неправильна електронна пошта або пароль"
|
msgstr "Неправильна електронна пошта або пароль"
|
||||||
|
|
@ -1052,22 +1052,22 @@ msgstr "Люди з підтвердженням геопозицією"
|
||||||
msgid "Location:"
|
msgid "Location:"
|
||||||
msgstr "Геопозиція:"
|
msgstr "Геопозиція:"
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/user_session_html/new.html.heex:136
|
#: lib/who_need_help_web/controllers/user_session_html/new.html.heex:146
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Log in and stay logged in"
|
msgid "Log in and stay logged in"
|
||||||
msgstr "Увійти й залишатися в системі"
|
msgstr "Увійти й залишатися в системі"
|
||||||
|
|
||||||
#: lib/who_need_help/accounts/user_notifier.ex:56
|
#: lib/who_need_help/accounts/user_notifier.ex:71
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Log in instructions"
|
msgid "Log in instructions"
|
||||||
msgstr "Інструкції для входу"
|
msgstr "Інструкції для входу"
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/user_session_html/new.html.heex:139
|
#: lib/who_need_help_web/controllers/user_session_html/new.html.heex:149
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Log in only this time"
|
msgid "Log in only this time"
|
||||||
msgstr "Увійти лише зараз"
|
msgstr "Увійти лише зараз"
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/user_session_controller.ex:117
|
#: lib/who_need_help_web/controllers/user_session_controller.ex:125
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Logged out successfully."
|
msgid "Logged out successfully."
|
||||||
msgstr "Ви успішно вийшли."
|
msgstr "Ви успішно вийшли."
|
||||||
|
|
@ -1416,7 +1416,7 @@ msgstr "Батьківська категорія (необов’язково)"
|
||||||
msgid "Participant"
|
msgid "Participant"
|
||||||
msgstr "Учасник"
|
msgstr "Учасник"
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/user_session_html/new.html.heex:130
|
#: lib/who_need_help_web/controllers/user_session_html/new.html.heex:140
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Password"
|
msgid "Password"
|
||||||
msgstr "Пароль"
|
msgstr "Пароль"
|
||||||
|
|
@ -1613,6 +1613,7 @@ msgstr ""
|
||||||
msgid "Rating"
|
msgid "Rating"
|
||||||
msgstr "Оцінка"
|
msgstr "Оцінка"
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_html/complete.html.heex:80
|
||||||
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:43
|
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:43
|
||||||
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:90
|
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:90
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
|
|
@ -2045,7 +2046,7 @@ msgstr "Браузеру не вдалося передати вашу геоп
|
||||||
msgid "The last administrator cannot demote themselves."
|
msgid "The last administrator cannot demote themselves."
|
||||||
msgstr "Останній адміністратор не може понизити власну роль."
|
msgstr "Останній адміністратор не може понизити власну роль."
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/user_session_controller.ex:37
|
#: lib/who_need_help_web/controllers/user_session_controller.ex:44
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "The link is invalid or it has expired."
|
msgid "The link is invalid or it has expired."
|
||||||
msgstr "Посилання недійсне або прострочене."
|
msgstr "Посилання недійсне або прострочене."
|
||||||
|
|
@ -2176,7 +2177,8 @@ msgstr "Сьогодні"
|
||||||
msgid "Too many actions in the configured time window."
|
msgid "Too many actions in the configured time window."
|
||||||
msgstr "Забагато дій протягом налаштованого проміжку часу."
|
msgstr "Забагато дій протягом налаштованого проміжку часу."
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/google_auth_controller.ex:180
|
#: lib/who_need_help_web/controllers/google_auth_controller.ex:139
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_controller.ex:309
|
||||||
#: lib/who_need_help_web/controllers/user_registration_controller.ex:49
|
#: lib/who_need_help_web/controllers/user_registration_controller.ex:49
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Too many registration attempts in the configured time window."
|
msgid "Too many registration attempts in the configured time window."
|
||||||
|
|
@ -2187,7 +2189,8 @@ msgstr "Забагато спроб реєстрації протягом нал
|
||||||
msgid "Too many requests in the configured time window."
|
msgid "Too many requests in the configured time window."
|
||||||
msgstr "Забагато запитів протягом налаштованого проміжку часу."
|
msgstr "Забагато запитів протягом налаштованого проміжку часу."
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/user_session_controller.ex:102
|
#: lib/who_need_help_web/controllers/google_auth_controller.ex:189
|
||||||
|
#: lib/who_need_help_web/controllers/user_session_controller.ex:110
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Too many sign-in emails in the configured time window."
|
msgid "Too many sign-in emails in the configured time window."
|
||||||
msgstr "Забагато листів для входу протягом налаштованого проміжку часу."
|
msgstr "Забагато листів для входу протягом налаштованого проміжку часу."
|
||||||
|
|
@ -2296,7 +2299,7 @@ msgstr "Користувач"
|
||||||
msgid "User blocked. Their requests and new messages are hidden."
|
msgid "User blocked. Their requests and new messages are hidden."
|
||||||
msgstr "Користувача заблоковано. Його заявки й нові повідомлення приховано."
|
msgstr "Користувача заблоковано. Його заявки й нові повідомлення приховано."
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/user_session_controller.ex:25
|
#: lib/who_need_help_web/controllers/user_session_controller.ex:31
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "User confirmed successfully."
|
msgid "User confirmed successfully."
|
||||||
msgstr "Користувача успішно підтверджено."
|
msgstr "Користувача успішно підтверджено."
|
||||||
|
|
@ -2352,9 +2355,9 @@ msgstr "Відкриті відгуки"
|
||||||
msgid "Waiting for a nearby volunteer."
|
msgid "Waiting for a nearby volunteer."
|
||||||
msgstr "Очікуємо помічника поруч."
|
msgstr "Очікуємо помічника поруч."
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/google_auth_controller.ex:137
|
#: lib/who_need_help_web/controllers/google_auth_controller.ex:266
|
||||||
#: lib/who_need_help_web/controllers/user_session_controller.ex:26
|
#: lib/who_need_help_web/controllers/user_session_controller.ex:32
|
||||||
#: lib/who_need_help_web/controllers/user_session_controller.ex:51
|
#: lib/who_need_help_web/controllers/user_session_controller.ex:58
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Welcome back!"
|
msgid "Welcome back!"
|
||||||
msgstr "З поверненням!"
|
msgstr "З поверненням!"
|
||||||
|
|
@ -2569,6 +2572,7 @@ msgstr "активність"
|
||||||
msgid "activity message"
|
msgid "activity message"
|
||||||
msgstr "повідомлення активності"
|
msgstr "повідомлення активності"
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_html/complete.html.heex:85
|
||||||
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:48
|
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:48
|
||||||
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:95
|
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:95
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
|
|
@ -2883,7 +2887,7 @@ msgstr "Вибраний запис більше недоступний."
|
||||||
msgid "The settings form is invalid."
|
msgid "The settings form is invalid."
|
||||||
msgstr "Форму налаштувань заповнено неправильно."
|
msgstr "Форму налаштувань заповнено неправильно."
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/user_session_controller.ex:111
|
#: lib/who_need_help_web/controllers/user_session_controller.ex:119
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "The sign-in form is invalid."
|
msgid "The sign-in form is invalid."
|
||||||
msgstr "Форму входу заповнено неправильно."
|
msgstr "Форму входу заповнено неправильно."
|
||||||
|
|
@ -2908,7 +2912,7 @@ msgstr "Ця пропозиція більше недоступна."
|
||||||
msgid "This request has expired."
|
msgid "This request has expired."
|
||||||
msgstr "Термін дії цієї заявки минув."
|
msgstr "Термін дії цієї заявки минув."
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/user_session_controller.ex:60
|
#: lib/who_need_help_web/controllers/user_session_controller.ex:68
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Too many sign-in attempts in the configured time window."
|
msgid "Too many sign-in attempts in the configured time window."
|
||||||
msgstr "Забагато спроб входу протягом налаштованого проміжку часу."
|
msgstr "Забагато спроб входу протягом налаштованого проміжку часу."
|
||||||
|
|
@ -2943,7 +2947,7 @@ msgstr "Забагато запитів на зміну email протягом
|
||||||
msgid "A Google account is connected. You can use it to sign in."
|
msgid "A Google account is connected. You can use it to sign in."
|
||||||
msgstr "Обліковий запис Google підключено. Тепер за його допомогою можна входити."
|
msgstr "Обліковий запис Google підключено. Тепер за його допомогою можна входити."
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/google_auth_controller.ex:207
|
#: lib/who_need_help_web/controllers/google_auth_controller.ex:336
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "A different Google account is already connected."
|
msgid "A different Google account is already connected."
|
||||||
msgstr "Уже підключено інший обліковий запис Google."
|
msgstr "Уже підключено інший обліковий запис Google."
|
||||||
|
|
@ -2953,12 +2957,8 @@ msgstr "Уже підключено інший обліковий запис Goo
|
||||||
msgid "A password is not required. We will email a one-time confirmation link. You can add a password later in account settings."
|
msgid "A password is not required. We will email a one-time confirmation link. You can add a password later in account settings."
|
||||||
msgstr "Пароль не обов’язковий. Ми надішлемо на email одноразове посилання для підтвердження. Пароль можна додати пізніше в налаштуваннях облікового запису."
|
msgstr "Пароль не обов’язковий. Ми надішлемо на email одноразове посилання для підтвердження. Пароль можна додати пізніше в налаштуваннях облікового запису."
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/google_auth_controller.ex:170
|
#: lib/who_need_help_web/controllers/google_auth_controller.ex:42
|
||||||
#, elixir-autogen, elixir-format
|
#: lib/who_need_help_web/controllers/google_auth_controller.ex:123
|
||||||
msgid "An account with this email already exists. Sign in by email or password, then connect Google in account settings."
|
|
||||||
msgstr "Обліковий запис із таким email уже існує. Увійдіть за email або паролем, а потім підключіть Google у налаштуваннях облікового запису."
|
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/google_auth_controller.ex:37
|
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Confirm that you are 18 or older and accept the safety rules first."
|
msgid "Confirm that you are 18 or older and accept the safety rules first."
|
||||||
msgstr "Спочатку підтвердьте, що вам уже виповнилося 18 років, і прийміть правила безпеки."
|
msgstr "Спочатку підтвердьте, що вам уже виповнилося 18 років, і прийміть правила безпеки."
|
||||||
|
|
@ -2978,17 +2978,17 @@ msgstr "Підключайте Google лише після входу тут. М
|
||||||
msgid "Create account and email me a link"
|
msgid "Create account and email me a link"
|
||||||
msgstr "Створити обліковий запис і надіслати посилання на email"
|
msgstr "Створити обліковий запис і надіслати посилання на email"
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/user_session_html/new.html.heex:99
|
#: lib/who_need_help_web/controllers/user_session_html/new.html.heex:109
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Email me a sign-in link"
|
msgid "Email me a sign-in link"
|
||||||
msgstr "Надіслати посилання для входу на email"
|
msgstr "Надіслати посилання для входу на email"
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/google_auth_controller.ex:215
|
#: lib/who_need_help_web/controllers/google_auth_controller.ex:344
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Google account connection session is invalid."
|
msgid "Google account connection session is invalid."
|
||||||
msgstr "Сесія підключення облікового запису Google недійсна."
|
msgstr "Сесія підключення облікового запису Google недійсна."
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/google_auth_controller.ex:97
|
#: lib/who_need_help_web/controllers/google_auth_controller.ex:226
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Google did not provide a verified email address."
|
msgid "Google did not provide a verified email address."
|
||||||
msgstr "Google не надав підтверджену адресу email."
|
msgstr "Google не надав підтверджену адресу email."
|
||||||
|
|
@ -2998,32 +2998,34 @@ msgstr "Google не надав підтверджену адресу email."
|
||||||
msgid "Google sign-in"
|
msgid "Google sign-in"
|
||||||
msgstr "Вхід через Google"
|
msgstr "Вхід через Google"
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/google_auth_controller.ex:197
|
#: lib/who_need_help_web/controllers/google_auth_controller.ex:326
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Google sign-in connected."
|
msgid "Google sign-in connected."
|
||||||
msgstr "Вхід через Google підключено."
|
msgstr "Вхід через Google підключено."
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/google_auth_controller.ex:123
|
#: lib/who_need_help_web/controllers/google_auth_controller.ex:252
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Google sign-in could not be started."
|
msgid "Google sign-in could not be started."
|
||||||
msgstr "Не вдалося розпочати вхід через Google."
|
msgstr "Не вдалося розпочати вхід через Google."
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/google_auth_controller.ex:102
|
#: lib/who_need_help_web/controllers/google_auth_controller.ex:231
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Google sign-in failed. Please try again."
|
msgid "Google sign-in failed. Please try again."
|
||||||
msgstr "Не вдалося увійти через Google. Спробуйте ще раз."
|
msgstr "Не вдалося увійти через Google. Спробуйте ще раз."
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/google_auth_controller.ex:128
|
#: lib/who_need_help_web/controllers/google_auth_controller.ex:257
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Google sign-in is not configured yet."
|
msgid "Google sign-in is not configured yet."
|
||||||
msgstr "Вхід через Google ще не налаштовано."
|
msgstr "Вхід через Google ще не налаштовано."
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/google_auth_controller.ex:87
|
#: lib/who_need_help_web/controllers/google_auth_controller.ex:97
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_controller.ex:216
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_controller.ex:399
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Google sign-in session expired. Please start again."
|
msgid "Google sign-in session expired. Please start again."
|
||||||
msgstr "Сесія входу через Google завершилася. Почніть заново."
|
msgstr "Сесія входу через Google завершилася. Почніть заново."
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/google_auth_controller.ex:91
|
#: lib/who_need_help_web/controllers/google_auth_controller.ex:220
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Google sign-in session is invalid."
|
msgid "Google sign-in session is invalid."
|
||||||
msgstr "Сесія входу через Google недійсна."
|
msgstr "Сесія входу через Google недійсна."
|
||||||
|
|
@ -3040,52 +3042,44 @@ msgstr "Вхід через Google стане доступним після на
|
||||||
msgid "Sending link..."
|
msgid "Sending link..."
|
||||||
msgstr "Надсилаємо посилання..."
|
msgstr "Надсилаємо посилання..."
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/user_session_html/new.html.heex:74
|
|
||||||
#, elixir-autogen, elixir-format
|
|
||||||
msgid "Sign in with Google"
|
|
||||||
msgstr "Увійти через Google"
|
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:51
|
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:51
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Sign up with Google"
|
msgid "Sign up with Google"
|
||||||
msgstr "Зареєструватися через Google"
|
msgstr "Зареєструватися через Google"
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/google_auth_controller.ex:202
|
#: lib/who_need_help_web/controllers/google_auth_controller.ex:331
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "That Google account belongs to another local account."
|
msgid "That Google account belongs to another local account."
|
||||||
msgstr "Цей обліковий запис Google належить іншому локальному обліковому запису."
|
msgstr "Цей обліковий запис Google належить іншому локальному обліковому запису."
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/google_auth_controller.ex:45
|
#: lib/who_need_help_web/controllers/google_auth_controller.ex:50
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_controller.ex:164
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "The Google registration form is invalid."
|
msgid "The Google registration form is invalid."
|
||||||
msgstr "Форму реєстрації через Google заповнено неправильно."
|
msgstr "Форму реєстрації через Google заповнено неправильно."
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/google_auth_controller.ex:260
|
#: lib/who_need_help_web/controllers/google_auth_controller.ex:405
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "This Google account cannot be used right now."
|
msgid "This Google account cannot be used right now."
|
||||||
msgstr "Цей обліковий запис Google зараз не можна використовувати."
|
msgstr "Цей обліковий запис Google зараз не можна використовувати."
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/google_auth_controller.ex:144
|
#: lib/who_need_help_web/controllers/user_session_html/new.html.heex:119
|
||||||
#, elixir-autogen, elixir-format
|
|
||||||
msgid "This Google account is not connected yet. Create an account or sign in by email and connect Google in account settings."
|
|
||||||
msgstr "Цей обліковий запис Google ще не підключено. Створіть обліковий запис або увійдіть за email і підключіть Google у налаштуваннях."
|
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/user_session_html/new.html.heex:109
|
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "This works only if you previously added a password in account settings."
|
msgid "This works only if you previously added a password in account settings."
|
||||||
msgstr "Це працює, лише якщо ви раніше додали пароль у налаштуваннях облікового запису."
|
msgstr "Це працює, лише якщо ви раніше додали пароль у налаштуваннях облікового запису."
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/user_session_html/new.html.heex:105
|
#: lib/who_need_help_web/controllers/user_session_html/new.html.heex:115
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Use a password instead"
|
msgid "Use a password instead"
|
||||||
msgstr "Увійти за паролем"
|
msgstr "Увійти за паролем"
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/user_session_html/new.html.heex:96
|
#: lib/who_need_help_web/controllers/user_session_html/new.html.heex:106
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "We will send a one-time sign-in link. No password is required."
|
msgid "We will send a one-time sign-in link. No password is required."
|
||||||
msgstr "Ми надішлемо одноразове посилання для входу. Пароль не потрібен."
|
msgstr "Ми надішлемо одноразове посилання для входу. Пароль не потрібен."
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/google_auth_controller.ex:163
|
#: lib/who_need_help_web/controllers/google_auth_controller.ex:116
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_controller.ex:288
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Your account was created with Google."
|
msgid "Your account was created with Google."
|
||||||
msgstr "Ваш обліковий запис створено через Google."
|
msgstr "Ваш обліковий запис створено через Google."
|
||||||
|
|
@ -3110,12 +3104,12 @@ msgstr "Відключити Google"
|
||||||
msgid "Disconnect Google sign-in from this account?"
|
msgid "Disconnect Google sign-in from this account?"
|
||||||
msgstr "Відключити вхід через Google для цього облікового запису?"
|
msgstr "Відключити вхід через Google для цього облікового запису?"
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/google_auth_controller.ex:60
|
#: lib/who_need_help_web/controllers/google_auth_controller.ex:65
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Google sign-in disconnected."
|
msgid "Google sign-in disconnected."
|
||||||
msgstr "Вхід через Google відключено."
|
msgstr "Вхід через Google відключено."
|
||||||
|
|
||||||
#: lib/who_need_help_web/controllers/google_auth_controller.ex:65
|
#: lib/who_need_help_web/controllers/google_auth_controller.ex:70
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "No Google account is connected."
|
msgid "No Google account is connected."
|
||||||
msgstr "Обліковий запис Google не підключено."
|
msgstr "Обліковий запис Google не підключено."
|
||||||
|
|
@ -3749,6 +3743,7 @@ msgstr "Видалити мій обліковий запис Who Need Help"
|
||||||
msgid "Please delete my account and associated personal data."
|
msgid "Please delete my account and associated personal data."
|
||||||
msgstr "Будь ласка, видаліть мій обліковий запис і пов’язані персональні дані."
|
msgstr "Будь ласка, видаліть мій обліковий запис і пов’язані персональні дані."
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_html/complete.html.heex:76
|
||||||
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:39
|
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:39
|
||||||
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:101
|
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:101
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
|
|
@ -3760,12 +3755,14 @@ msgstr "Мені 18 років або більше, і я приймаю Умо
|
||||||
msgid "Privacy"
|
msgid "Privacy"
|
||||||
msgstr "Конфіденційність"
|
msgstr "Конфіденційність"
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_html/complete.html.heex:82
|
||||||
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:45
|
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:45
|
||||||
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:92
|
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:92
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Privacy Policy"
|
msgid "Privacy Policy"
|
||||||
msgstr "Політика конфіденційності"
|
msgstr "Політика конфіденційності"
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_html/complete.html.heex:84
|
||||||
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:47
|
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:47
|
||||||
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:94
|
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:94
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
|
|
@ -3773,12 +3770,14 @@ msgid "Safety Rules"
|
||||||
msgstr "Правила безпеки"
|
msgstr "Правила безпеки"
|
||||||
|
|
||||||
#: lib/who_need_help_web/components/layouts.ex:149
|
#: lib/who_need_help_web/components/layouts.ex:149
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_html/complete.html.heex:81
|
||||||
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:44
|
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:44
|
||||||
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:91
|
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:91
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Terms"
|
msgid "Terms"
|
||||||
msgstr "Умови"
|
msgstr "Умови"
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_html/complete.html.heex:83
|
||||||
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:46
|
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:46
|
||||||
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:93
|
#: lib/who_need_help_web/controllers/user_registration_html/new.html.heex:93
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
|
|
@ -4102,3 +4101,111 @@ msgstr "Ви самі обираєте видимість. Точні поточ
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "You stay in control of the match"
|
msgid "You stay in control of the match"
|
||||||
msgstr "Ви контролюєте взаємодію"
|
msgstr "Ви контролюєте взаємодію"
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_html/complete.html.heex:52
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "After this confirmation, future Google sign-ins will take one click."
|
||||||
|
msgstr "Після цього підтвердження подальший вхід через Google виконуватиметься одним натисканням."
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_html/complete.html.heex:99
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Cancel and use another sign-in method"
|
||||||
|
msgstr "Скасувати й вибрати інший спосіб входу"
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_html/complete.html.heex:35
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Confirm access once so nobody can attach Google to your account using only a matching email address."
|
||||||
|
msgstr "Один раз підтвердьте доступ, щоб ніхто не зміг прив’язати Google до вашого облікового запису лише за збігом email."
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_html/complete.html.heex:5
|
||||||
|
#: lib/who_need_help_web/controllers/user_session_html/new.html.heex:74
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Continue with Google"
|
||||||
|
msgstr "Продовжити з Google"
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_html/complete.html.heex:91
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Create account and continue"
|
||||||
|
msgstr "Створити обліковий запис і продовжити"
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_html/complete.html.heex:58
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Create your Who Need Help account"
|
||||||
|
msgstr "Створіть обліковий запис Who Need Help"
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_html/complete.html.heex:89
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Creating account..."
|
||||||
|
msgstr "Створюємо обліковий запис..."
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_html/complete.html.heex:43
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Email me a verification link"
|
||||||
|
msgstr "Надіслати посилання для підтвердження на email"
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/controllers/user_session_controller.ex:158
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Google sign-in connected. You can use it next time."
|
||||||
|
msgstr "Вхід через Google підключено. Наступного разу можна скористатися ним."
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_html/complete.html.heex:7
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Google verified your identity. Finish this one-time step to continue."
|
||||||
|
msgstr "Google підтвердив вашу особу. Виконайте цей разовий крок, щоб продовжити."
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_html/complete.html.heex:60
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "No password is required. Google will be connected as your sign-in method."
|
||||||
|
msgstr "Пароль не потрібен. Google буде підключено як спосіб входу."
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_html/complete.html.heex:42
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Sending..."
|
||||||
|
msgstr "Надсилаємо..."
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/controllers/user_session_html/new.html.heex:88
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Sign in to %{email} once to connect Google. You can use the email link or your existing password."
|
||||||
|
msgstr "Один раз увійдіть до %{email}, щоб підключити Google. Можна скористатися посиланням із листа або чинним паролем."
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_html/complete.html.heex:33
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "This email already has an account"
|
||||||
|
msgstr "Для цього email уже є обліковий запис"
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_controller.ex:131
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_controller.ex:153
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_controller.ex:297
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "This email already has an account. Confirm it once to connect Google."
|
||||||
|
msgstr "Для цього email уже є обліковий запис. Один раз підтвердьте його, щоб підключити Google."
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_html/complete.html.heex:48
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Use my password instead"
|
||||||
|
msgstr "Скористатися паролем"
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_html/complete.html.heex:25
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Verified"
|
||||||
|
msgstr "Підтверджено"
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/controllers/google_auth_controller.ex:178
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "We sent a verification link to %{email}. Open it to finish connecting Google."
|
||||||
|
msgstr "Ми надіслали посилання для підтвердження на %{email}. Відкрийте його, щоб завершити підключення Google."
|
||||||
|
|
||||||
|
#: lib/who_need_help_web/controllers/user_session_controller.ex:171
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "You are signed in, but Google could not be connected. Try again in account settings."
|
||||||
|
msgstr "Ви ввійшли, але підключити Google не вдалося. Повторіть спробу в налаштуваннях облікового запису."
|
||||||
|
|
||||||
|
#: lib/who_need_help/accounts/user_notifier.ex:57
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Confirm Google sign-in"
|
||||||
|
msgstr "Підтвердьте вхід через Google"
|
||||||
|
|
||||||
|
#: lib/who_need_help/accounts/user_notifier.ex:58
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Hi %{email},\n\nUse the secure link below to sign in and connect Google to your Who Need Help account:\n\n%{url}\n\nIf you did not request this, ignore this email. Google will not be connected."
|
||||||
|
msgstr "Вітаємо, %{email}!\n\nПерейдіть за захищеним посиланням нижче, щоб увійти й підключити Google до облікового запису Who Need Help:\n\n%{url}\n\nЯкщо ви не запитували цю дію, проігноруйте лист. Google не буде підключено."
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ defmodule WhoNeedHelpWeb.GoogleAuthControllerTest do
|
||||||
alias WhoNeedHelp.Trust.AuditEvent
|
alias WhoNeedHelp.Trust.AuditEvent
|
||||||
|
|
||||||
import WhoNeedHelp.AccountsFixtures
|
import WhoNeedHelp.AccountsFixtures
|
||||||
|
import Swoosh.TestAssertions
|
||||||
|
|
||||||
test "starts a login flow with callback state, nonce, and PKCE session data", %{conn: conn} do
|
test "starts a login flow with callback state, nonce, and PKCE session data", %{conn: conn} do
|
||||||
conn = post(conn, ~p"/auth/google/login")
|
conn = post(conn, ~p"/auth/google/login")
|
||||||
|
|
@ -68,7 +69,7 @@ defmodule WhoNeedHelpWeb.GoogleAuthControllerTest do
|
||||||
assert user_id == user.id
|
assert user_id == user.id
|
||||||
end
|
end
|
||||||
|
|
||||||
test "does not automatically merge an existing email account", %{conn: conn} do
|
test "requires local-account verification before linking a matching email", %{conn: conn} do
|
||||||
user = user_fixture()
|
user = user_fixture()
|
||||||
|
|
||||||
conn =
|
conn =
|
||||||
|
|
@ -81,10 +82,14 @@ defmodule WhoNeedHelpWeb.GoogleAuthControllerTest do
|
||||||
~p"/auth/google/callback?code=code&state=google-test-state&uid=new-google&email=#{user.email}"
|
~p"/auth/google/callback?code=code&state=google-test-state&uid=new-google&email=#{user.email}"
|
||||||
)
|
)
|
||||||
|
|
||||||
assert redirected_to(conn) == ~p"/users/log-in"
|
assert redirected_to(conn) == ~p"/auth/google/complete"
|
||||||
assert Phoenix.Flash.get(conn.assigns.flash, :error) =~ "already exists"
|
assert Phoenix.Flash.get(conn.assigns.flash, :info) =~ "Confirm it once"
|
||||||
refute get_session(conn, :user_token)
|
refute get_session(conn, :user_token)
|
||||||
refute Repo.get_by(AuthIdentity, provider: :google, provider_uid: "new-google")
|
refute Repo.get_by(AuthIdentity, provider: :google, provider_uid: "new-google")
|
||||||
|
|
||||||
|
html = conn |> recycle() |> get(~p"/auth/google/complete") |> html_response(200)
|
||||||
|
assert html =~ "This email already has an account"
|
||||||
|
assert html =~ "Email me a verification link"
|
||||||
end
|
end
|
||||||
|
|
||||||
test "logs in only through an identity already linked to the local account", %{conn: conn} do
|
test "logs in only through an identity already linked to the local account", %{conn: conn} do
|
||||||
|
|
@ -110,7 +115,7 @@ defmodule WhoNeedHelpWeb.GoogleAuthControllerTest do
|
||||||
assert get_session(conn, :user_token)
|
assert get_session(conn, :user_token)
|
||||||
end
|
end
|
||||||
|
|
||||||
test "does not create an account from the login-only flow", %{conn: conn} do
|
test "continues an unlinked Google user into account creation", %{conn: conn} do
|
||||||
email = unique_user_email()
|
email = unique_user_email()
|
||||||
|
|
||||||
conn =
|
conn =
|
||||||
|
|
@ -121,10 +126,119 @@ defmodule WhoNeedHelpWeb.GoogleAuthControllerTest do
|
||||||
~p"/auth/google/callback?code=code&state=google-test-state&uid=unknown-google&email=#{email}"
|
~p"/auth/google/callback?code=code&state=google-test-state&uid=unknown-google&email=#{email}"
|
||||||
)
|
)
|
||||||
|
|
||||||
assert redirected_to(conn) == ~p"/users/log-in"
|
assert redirected_to(conn) == ~p"/auth/google/complete"
|
||||||
assert Phoenix.Flash.get(conn.assigns.flash, :error) =~ "not connected"
|
|
||||||
refute Accounts.get_user_by_email(email)
|
refute Accounts.get_user_by_email(email)
|
||||||
refute get_session(conn, :user_token)
|
refute get_session(conn, :user_token)
|
||||||
|
|
||||||
|
html = conn |> recycle() |> get(~p"/auth/google/complete") |> html_response(200)
|
||||||
|
assert html =~ "Create your Who Need Help account"
|
||||||
|
assert html =~ email
|
||||||
|
end
|
||||||
|
|
||||||
|
test "creates and links an unlinked Google user after terms acceptance", %{conn: conn} do
|
||||||
|
email = unique_user_email()
|
||||||
|
|
||||||
|
conn =
|
||||||
|
conn
|
||||||
|
|> post(~p"/auth/google/login")
|
||||||
|
|> recycle()
|
||||||
|
|> get(
|
||||||
|
~p"/auth/google/callback?code=code&state=google-test-state&uid=continue-google&email=#{email}&name=Continued%20Helper"
|
||||||
|
)
|
||||||
|
|> recycle()
|
||||||
|
|> post(~p"/auth/google/complete-registration", %{
|
||||||
|
"google_registration" => %{"locale" => "uk", "terms_accepted" => "true"}
|
||||||
|
})
|
||||||
|
|
||||||
|
assert redirected_to(conn) == ~p"/"
|
||||||
|
assert get_session(conn, :user_token)
|
||||||
|
|
||||||
|
user = Accounts.get_user_by_email(email)
|
||||||
|
assert user.confirmed_at
|
||||||
|
assert user.accepted_terms_at
|
||||||
|
assert user.locale == "uk"
|
||||||
|
assert user.display_name == "Continued Helper"
|
||||||
|
|
||||||
|
assert %AuthIdentity{user_id: user_id} =
|
||||||
|
Repo.get_by!(AuthIdentity, provider: :google, provider_uid: "continue-google")
|
||||||
|
|
||||||
|
assert user_id == user.id
|
||||||
|
end
|
||||||
|
|
||||||
|
test "does not create a continued Google account without accepting terms", %{conn: conn} do
|
||||||
|
email = unique_user_email()
|
||||||
|
|
||||||
|
conn =
|
||||||
|
conn
|
||||||
|
|> post(~p"/auth/google/login")
|
||||||
|
|> recycle()
|
||||||
|
|> get(
|
||||||
|
~p"/auth/google/callback?code=code&state=google-test-state&uid=no-terms-google&email=#{email}"
|
||||||
|
)
|
||||||
|
|> recycle()
|
||||||
|
|> post(~p"/auth/google/complete-registration", %{
|
||||||
|
"google_registration" => %{"locale" => "en", "terms_accepted" => "false"}
|
||||||
|
})
|
||||||
|
|
||||||
|
assert redirected_to(conn) == ~p"/auth/google/complete"
|
||||||
|
assert Phoenix.Flash.get(conn.assigns.flash, :error) =~ "18 or older"
|
||||||
|
refute Accounts.get_user_by_email(email)
|
||||||
|
refute Repo.get_by(AuthIdentity, provider: :google, provider_uid: "no-terms-google")
|
||||||
|
end
|
||||||
|
|
||||||
|
test "links an existing account after one magic-link verification", %{conn: conn} do
|
||||||
|
user = user_fixture()
|
||||||
|
assert_email_sent()
|
||||||
|
|
||||||
|
conn =
|
||||||
|
conn
|
||||||
|
|> post(~p"/auth/google/login")
|
||||||
|
|> recycle()
|
||||||
|
|> get(
|
||||||
|
~p"/auth/google/callback?code=code&state=google-test-state&uid=verified-existing-google&email=#{user.email}"
|
||||||
|
)
|
||||||
|
|> recycle()
|
||||||
|
|> post(~p"/auth/google/verify-existing")
|
||||||
|
|
||||||
|
assert redirected_to(conn) == ~p"/users/log-in"
|
||||||
|
assert Phoenix.Flash.get(conn.assigns.flash, :info) =~ "finish connecting Google"
|
||||||
|
|
||||||
|
assert_email_sent(fn email ->
|
||||||
|
email.subject == "Confirm Google sign-in" and
|
||||||
|
email.text_body =~ "connect Google to your Who Need Help account" and
|
||||||
|
email.text_body =~ "google_link=" and email.text_body =~ "#token="
|
||||||
|
end)
|
||||||
|
|
||||||
|
pending_token = get_session(conn, "pending_google_identity")
|
||||||
|
assert is_binary(pending_token)
|
||||||
|
{token, _hashed_token} = generate_user_magic_link_token(user)
|
||||||
|
|
||||||
|
conn =
|
||||||
|
build_conn()
|
||||||
|
|> get(~p"/users/log-in?google_link=#{pending_token}")
|
||||||
|
|> recycle()
|
||||||
|
|> post(~p"/users/log-in", %{"user" => %{"token" => token}})
|
||||||
|
|
||||||
|
assert redirected_to(conn) == ~p"/"
|
||||||
|
assert get_session(conn, :user_token)
|
||||||
|
assert Phoenix.Flash.get(conn.assigns.flash, :info) =~ "Google sign-in connected"
|
||||||
|
|
||||||
|
identity =
|
||||||
|
Repo.get_by!(AuthIdentity,
|
||||||
|
provider: :google,
|
||||||
|
provider_uid: "verified-existing-google"
|
||||||
|
)
|
||||||
|
|
||||||
|
assert identity.user_id == user.id
|
||||||
|
|
||||||
|
assert %AuditEvent{actor_id: actor_id, metadata: metadata} =
|
||||||
|
Repo.get_by!(AuditEvent,
|
||||||
|
action: "auth_identity.connected",
|
||||||
|
target_id: identity.id
|
||||||
|
)
|
||||||
|
|
||||||
|
assert actor_id == user.id
|
||||||
|
assert metadata["method"] == "verified_local_sign_in"
|
||||||
end
|
end
|
||||||
|
|
||||||
test "rejects unverified Google email and consumes the flow session", %{conn: conn} do
|
test "rejects unverified Google email and consumes the flow session", %{conn: conn} do
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ defmodule WhoNeedHelpWeb.UserSessionControllerTest do
|
||||||
assert response =~ "Log in"
|
assert response =~ "Log in"
|
||||||
assert response =~ ~p"/users/register"
|
assert response =~ ~p"/users/register"
|
||||||
assert response =~ "Email me a sign-in link"
|
assert response =~ "Email me a sign-in link"
|
||||||
assert response =~ "Sign in with Google"
|
assert response =~ "Continue with Google"
|
||||||
assert response =~ "Use a password instead"
|
assert response =~ "Use a password instead"
|
||||||
assert response =~ ~s(id="magic-link-fragment-form")
|
assert response =~ ~s(id="magic-link-fragment-form")
|
||||||
assert response =~ ~s(hidden)
|
assert response =~ ~s(hidden)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user