Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
ku1ik committed May 23, 2024
2 parents 3e755d8 + 0ca4a76 commit edbfb9a
Show file tree
Hide file tree
Showing 91 changed files with 885 additions and 455 deletions.
3 changes: 3 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ RUN cd assets && \
COPY config/config.exs config/
COPY config/prod.exs config/

# ensure mime is recompiled later with our additional mime types
RUN mix deps.clean mime --build

RUN mix phx.digest

COPY config/*.exs config/
Expand Down
24 changes: 8 additions & 16 deletions assets/css/_base.scss
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,14 @@ body, main {
}
}

.c-page {
main {
h1 {
margin-top: 4rem;
}
}
}

.c-page .container > h1 {
margin-bottom: 2rem;
}
Expand Down Expand Up @@ -177,22 +185,6 @@ form {
}
}

.c-doc {
main {
h1 {
margin-top: 0;
margin-bottom: 1em;
}
}

.content {
h2 {
margin-top: 2em;
margin-bottom: 1em;
}
}
}

body pre {
background-color: #fff;
border-color: #ddd;
Expand Down
10 changes: 8 additions & 2 deletions assets/css/_recording_card.scss
Original file line number Diff line number Diff line change
Expand Up @@ -88,10 +88,12 @@ div.asciicast-card {

h3 {
margin: 0 0 6px 0;
font-size: 20px;
font-size: 18px;
display: flex;

.duration {
float: right;
margin: auto 0 auto auto;
padding-left: 1em;
font-size: 14px;
}
}
Expand All @@ -104,6 +106,10 @@ div.asciicast-card {
abbr {
border-bottom: 0;
}

.special-label {
float: right;
}
}
}
}
11 changes: 11 additions & 0 deletions assets/css/_user_edit.scss
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,15 @@
opacity: 0.7;
}
}

.danger-zone {
margin-top: 2em;
}
}

.c-user.a-delete {
h1 {
margin-top: 2rem;
margin-bottom: 2rem;
}
}
25 changes: 21 additions & 4 deletions config/config.exs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,16 @@ config :asciinema, AsciinemaWeb.Endpoint,
]
],
url: [host: "localhost"],
render_errors: [view: AsciinemaWeb.ErrorView, accepts: ~w(html json), layout: false],
render_errors: [
formats: [
html: AsciinemaWeb.ErrorHTML,
json: AsciinemaWeb.ErrorJSON,
txt: AsciinemaWeb.ErrorTEXT,
svg: AsciinemaWeb.ErrorTEXT,
xml: AsciinemaWeb.ErrorTEXT
],
layout: false
],
live_view: [signing_salt: "F3BMP7k9SZ-Y2SMJ"],
pubsub_server: Asciinema.PubSub

Expand All @@ -53,7 +62,17 @@ config :logger,
config :phoenix, :json_library, Jason

config :phoenix, :template_engines, md: PhoenixMarkdown.Engine
config :phoenix_template, :format_encoders, svg: Phoenix.HTML.Engine, xml: Phoenix.HTML.Engine

config :phoenix_template, :format_encoders,
cast: Jason,
svg: Phoenix.HTML.Engine,
xml: Phoenix.HTML.Engine

config :mime, :types, %{
"application/x-asciicast" => ["cast"]
}

config :asciinema, Asciinema.Emails.Mailer, adapter: Swoosh.Adapters.Local

config :sentry,
dsn: "https://public:[email protected]/1",
Expand All @@ -68,8 +87,6 @@ config :asciinema, Asciinema.FileStore.Local, path: "uploads/"

config :asciinema, Asciinema.FileCache, path: "cache/"

config :asciinema, Asciinema.Emails.Mailer, adapter: Bamboo.LocalAdapter

config :asciinema, :png_generator, Asciinema.PngGenerator.Rsvg

config :asciinema, Asciinema.PngGenerator.Rsvg,
Expand Down
30 changes: 15 additions & 15 deletions config/runtime.exs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,19 @@ if config_env() in [:prod, :dev] do
config :asciinema, Asciinema.FileCache, path: cache_path
end

config :ex_aws,
region: [{:system, "S3_REGION"}, {:system, "AWS_REGION"}],
access_key_id: [
{:system, "S3_ACCESS_KEY_ID"},
{:system, "AWS_ACCESS_KEY_ID"},
:instance_role
],
secret_access_key: [
{:system, "S3_SECRET_ACCESS_KEY"},
{:system, "AWS_SECRET_ACCESS_KEY"},
:instance_role
]

if bucket = env.("S3_BUCKET") do
config :asciinema, Asciinema.FileStore.S3,
bucket: bucket,
Expand All @@ -110,19 +123,6 @@ if config_env() in [:prod, :dev] do
config :asciinema, Asciinema.FileStore.Local,
path: Path.join(cache_path || "/var/cache/asciinema", "uploads")

config :ex_aws,
region: [{:system, "S3_REGION"}, {:system, "AWS_REGION"}],
access_key_id: [
{:system, "S3_ACCESS_KEY_ID"},
{:system, "AWS_ACCESS_KEY_ID"},
:instance_role
],
secret_access_key: [
{:system, "S3_SECRET_ACCESS_KEY"},
{:system, "AWS_SECRET_ACCESS_KEY"},
:instance_role
]

if endpoint = env.("S3_ENDPOINT") do
uri = URI.parse(endpoint)

Expand All @@ -143,8 +143,8 @@ if config_env() in [:prod, :dev] do

if smtp_host = env.("SMTP_HOST") do
config :asciinema, Asciinema.Emails.Mailer,
adapter: Bamboo.SMTPAdapter,
server: smtp_host,
adapter: Swoosh.Adapters.SMTP,
relay: smtp_host,
port: String.to_integer(env.("SMTP_PORT") || "587")

if username = env.("SMTP_USERNAME") do
Expand Down
5 changes: 3 additions & 2 deletions config/test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ if db_url = System.get_env("TEST_DATABASE_URL") do
System.put_env("DATABASE_URL", db_url)
end

# In test we don't send emails.
config :asciinema, Asciinema.Emails.Mailer, adapter: Swoosh.Adapters.Test

# Print only errors during test
config :logger, level: :error

Expand All @@ -37,6 +40,4 @@ config :asciinema, :snapshot_updater, Asciinema.Recordings.SnapshotUpdater.Noop

config :asciinema, Oban, testing: :manual

config :asciinema, Asciinema.Emails.Mailer, adapter: Bamboo.TestAdapter

config :asciinema, Asciinema.Telemetry, enabled: false
16 changes: 12 additions & 4 deletions lib/asciinema.ex
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,24 @@ defmodule Asciinema do
end
end

def send_login_email(identifier, sign_up_enabled?, routes) do
case Accounts.generate_login_url(identifier, sign_up_enabled?, routes) do
{:ok, {type, url, email}} ->
Emails.send_email(type, email, url)
def send_login_email(identifier, sign_up_enabled? \\ true)

def send_login_email(identifier, sign_up_enabled?) do
case Accounts.generate_login_token(identifier, sign_up_enabled?) do
{:ok, {type, token, email}} ->
Emails.send_email(type, email, token)

{:error, _reason} = result ->
result
end
end

def send_account_deletion_email(user) do
token = Accounts.generate_deletion_token(user)

Emails.send_email(:account_deletion, user.email, token)
end

defdelegate verify_login_token(token), to: Accounts

def merge_accounts(src_user, dst_user) do
Expand Down
27 changes: 18 additions & 9 deletions lib/asciinema/accounts.ex
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ defmodule Asciinema.Accounts do
alias Asciinema.Accounts.{User, ApiToken}
alias Asciinema.{Fonts, Repo, Themes}
alias Ecto.Changeset
alias Phoenix.Token

@valid_email_re ~r/^[A-Z0-9._%+-]+@([A-Z0-9-]+\.)+[A-Z]{2,}$/i
@valid_username_re ~r/^[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]$/
Expand Down Expand Up @@ -88,7 +89,7 @@ defmodule Asciinema.Accounts do
:theme_name,
:theme_prefer_original,
:terminal_font_family,
:asciicasts_private_by_default
:default_asciicast_visibility
])
|> validate_required([:email])
|> update_change(:email, &String.downcase/1)
Expand Down Expand Up @@ -123,24 +124,23 @@ defmodule Asciinema.Accounts do
from(u in q, where: is_nil(u.email))
end

def generate_login_url(identifier, sign_up_enabled?, routes) do
def generate_login_token(identifier, sign_up_enabled? \\ true)

def generate_login_token(identifier, sign_up_enabled?) do
case {lookup_user(identifier), sign_up_enabled?} do
{{_, %User{email: nil}}, _} ->
{:error, :email_missing}

{{_, %User{} = user}, _} ->
url = user |> login_token() |> routes.login_url()

{:ok, {:login, url, user.email}}
{:ok, {:login, login_token(user), user.email}}

{{:email, nil}, true} ->
changeset = change_user(%User{}, %{email: identifier})

if changeset.valid? do
email = changeset.changes.email
url = email |> signup_token() |> routes.signup_url()

{:ok, {:signup, url, email}}
{:ok, {:signup, signup_token(email), email}}
else
{:error, :email_invalid}
end
Expand All @@ -158,8 +158,6 @@ defmodule Asciinema.Accounts do
end
end

alias Phoenix.Token

def signup_token(email) do
Token.sign(config(:secret), "signup", email)
end
Expand Down Expand Up @@ -210,6 +208,17 @@ defmodule Asciinema.Accounts do
end
end

def generate_deletion_token(%User{id: user_id}) do
Token.sign(config(:secret), "acct-delete", user_id)
end

def verify_deletion_token(token) do
case Token.verify(config(:secret), "acct-delete", token, max_age: 3600) do
{:ok, user_id} -> {:ok, user_id}
{:error, _} -> {:error, :token_invalid}
end
end

def get_user_with_api_token(token, tmp_username \\ nil) do
case get_api_token(token) do
{:ok, %ApiToken{user: user}} ->
Expand Down
6 changes: 5 additions & 1 deletion lib/asciinema/accounts/user.ex
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,11 @@ defmodule Asciinema.Accounts.User do
field :theme_name, :string
field :theme_prefer_original, :boolean, default: true
field :terminal_font_family, :string
field :asciicasts_private_by_default, :boolean, default: true

field :default_asciicast_visibility, Ecto.Enum,
values: [:private, :unlisted, :public],
default: :unlisted

field :last_login_at, :utc_datetime_usec
field :is_admin, :boolean

Expand Down
13 changes: 4 additions & 9 deletions lib/asciinema/authorization.ex
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ defmodule Asciinema.Authorization do
alias Asciinema.Streaming.LiveStream

defmodule Policy do
def can?(_user, :show, %Asciicast{visibility: v}) when v in [:public, :unlisted], do: true
def can?(_user, :show, %LiveStream{visibility: v}) when v in [:public, :unlisted], do: true
def can?(nil, _action, _thing), do: false
def can?(%User{is_admin: true}, _action, _thing), do: true
Expand All @@ -15,13 +16,7 @@ defmodule Asciinema.Authorization do
def can?(_user, _action, _thing), do: false
end

def can?(user, action, thing) do
action =
case action do
:edit -> :update
action -> action
end

Policy.can?(user, action, thing)
end
def can?(user, :edit, thing), do: can?(user, :update, thing)
def can?(user, :iframe, thing), do: can?(user, :show, thing)
def can?(user, action, thing), do: Policy.can?(user, action, thing)
end
Loading

0 comments on commit edbfb9a

Please sign in to comment.