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 15, 2024
2 parents 1af2390 + b3a852d commit 3e755d8
Show file tree
Hide file tree
Showing 75 changed files with 805 additions and 466 deletions.
14 changes: 13 additions & 1 deletion assets/css/_base.scss
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
@import "./_source_sans_pro.css";
@import "./fonts/source_sans_pro.css";

html {
height: 100%;
Expand Down Expand Up @@ -142,6 +142,18 @@ form {
.col-form-label {
font-weight: 600;
}

.form-group.row {
margin-bottom: 1.5rem;
}

.form-check {
margin-bottom: 0.75em;
}

.visibility-radios {
padding-top: 0.375rem;
}
}

.special-label {
Expand Down
2 changes: 1 addition & 1 deletion assets/css/app.scss
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ $primary: #06989a;
@import "./_user_profile.scss";
@import "./_user_login.scss";
@import "./_user_edit.scss";
@import "./powerline-symbols.css";
@import "./fonts/powerline-symbols.css";
@import "./fonts/fira-code-nerd-font.css";
@import "./fonts/jetbrains-mono-nerd-font.css";
@import "~asciinema-player/dist/bundle/asciinema-player.css";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
@font-face {
font-family: 'Powerline Symbols';
src: local('Powerline Symbols'), local('PowerlineSymbols'), url('../static/fonts/PowerlineSymbols.otf') format('opentype');
src: local('Powerline Symbols'), local('PowerlineSymbols'), url('../../static/fonts/PowerlineSymbols.otf') format('opentype');
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,29 @@
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 300;
src: local('Source Sans Pro Light'), local('SourceSansPro-Light'), url('../static/fonts/SourceSansPro-Light.ttf') format('truetype');
src: local('Source Sans Pro Light'), local('SourceSansPro-Light'), url('../../static/fonts/SourceSansPro-Light.ttf') format('truetype');
}
@font-face {
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 400;
src: local('Source Sans Pro'), local('SourceSansPro-Regular'), url('../static/fonts/SourceSansPro-Regular.ttf') format('truetype');
src: local('Source Sans Pro'), local('SourceSansPro-Regular'), url('../../static/fonts/SourceSansPro-Regular.ttf') format('truetype');
}
@font-face {
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 600;
src: local('Source Sans Pro Semibold'), local('SourceSansPro-Semibold'), url('../static/fonts/SourceSansPro-Semibold.ttf') format('truetype');
src: local('Source Sans Pro Semibold'), local('SourceSansPro-Semibold'), url('../../static/fonts/SourceSansPro-Semibold.ttf') format('truetype');
}
@font-face {
font-family: 'Source Sans Pro';
font-style: normal;
font-weight: 700;
src: local('Source Sans Pro Bold'), local('SourceSansPro-Bold'), url('../static/fonts/SourceSansPro-Bold.ttf') format('truetype');
src: local('Source Sans Pro Bold'), local('SourceSansPro-Bold'), url('../../static/fonts/SourceSansPro-Bold.ttf') format('truetype');
}
@font-face {
font-family: 'Source Sans Pro';
font-style: italic;
font-weight: 400;
src: local('Source Sans Pro Italic'), local('SourceSansPro-It'), url('../static/fonts/SourceSansPro-Italic.ttf') format('truetype');
src: local('Source Sans Pro Italic'), local('SourceSansPro-It'), url('../../static/fonts/SourceSansPro-Italic.ttf') format('truetype');
}
6 changes: 4 additions & 2 deletions assets/css/iframe.scss
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
@import "./_source_sans_pro.css";
@import "./fonts/source_sans_pro.css";
@import "./fonts/fira-code-nerd-font.css";
@import "./fonts/jetbrains-mono-nerd-font.css";
@import "~asciinema-player/dist/bundle/asciinema-player.css";
@import "./powerline-symbols.css";
@import "./fonts/powerline-symbols.css";

body.iframe {
background-color: transparent;
Expand Down
8 changes: 7 additions & 1 deletion config/config.exs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@
# General application configuration
import Config

config :asciinema, :session_opts,
store: :cookie,
key: "_asciinema_key",
signing_salt: "qJL+3s0T",
same_site: "Lax"

config :asciinema,
ecto_repos: [Asciinema.Repo]

Expand Down Expand Up @@ -47,7 +53,7 @@ config :logger,
config :phoenix, :json_library, Jason

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

config :sentry,
dsn: "https://public:[email protected]/1",
Expand Down
3 changes: 3 additions & 0 deletions lib/asciinema.ex
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ defmodule Asciinema do
defdelegate verify_login_token(token), to: Accounts

def merge_accounts(src_user, dst_user) do
src_user = Accounts.find_user(src_user)
dst_user = Accounts.find_user(dst_user)

Repo.transact(fn ->
Recordings.reassign_asciicasts(src_user.id, dst_user.id)
Streaming.reassign_live_streams(src_user.id, dst_user.id)
Expand Down
21 changes: 17 additions & 4 deletions lib/asciinema/accounts.ex
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ defmodule Asciinema.Accounts do
alias Asciinema.{Fonts, Repo, Themes}
alias Ecto.Changeset

@valid_email_re ~r/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i
@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]$/

def fetch_user(id) do
Expand All @@ -20,6 +20,16 @@ defmodule Asciinema.Accounts do

def get_user(id), do: Repo.get(User, id)

def find_user(%User{} = user), do: user

def find_user(id) when is_integer(id), do: get_user(id)

def find_user(id) when is_binary(id) do
{_, user} = lookup_user(id)

user
end

def find_user_by_username(username) do
Repo.one(
from(u in User,
Expand All @@ -38,8 +48,9 @@ defmodule Asciinema.Accounts do
result =
%User{}
|> cast(attrs, [:email])
|> validate_format(:email, @valid_email_re)
|> validate_required([:email])
|> update_change(:email, &String.downcase/1)
|> validate_format(:email, @valid_email_re)
|> add_contraints()
|> Repo.insert()

Expand Down Expand Up @@ -79,6 +90,8 @@ defmodule Asciinema.Accounts do
:terminal_font_family,
:asciicasts_private_by_default
])
|> validate_required([:email])
|> update_change(:email, &String.downcase/1)
|> validate_format(:email, @valid_email_re)
|> validate_format(:username, @valid_username_re)
|> validate_length(:username, min: 2, max: 16)
Expand All @@ -100,7 +113,7 @@ defmodule Asciinema.Accounts do

user
|> change_user(params)
|> validate_required([:username, :email])
|> validate_required([:username])
|> Repo.update()
end

Expand Down Expand Up @@ -139,7 +152,7 @@ defmodule Asciinema.Accounts do

def lookup_user(identifier) when is_binary(identifier) do
if String.contains?(identifier, "@") do
{:email, Repo.get_by(User, email: identifier)}
{:email, Repo.get_by(User, email: String.downcase(identifier))}
else
{:username, find_user_by_username(identifier)}
end
Expand Down
13 changes: 1 addition & 12 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, %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
def can?(_user, :make_featured, %Asciicast{}), do: false
Expand All @@ -23,16 +24,4 @@ defmodule Asciinema.Authorization do

Policy.can?(user, action, thing)
end

defmodule ForbiddenError do
defexception plug_status: 403, message: "Forbidden"
end

def can!(user, action, thing) do
if can?(user, action, thing) do
:ok
else
raise ForbiddenError
end
end
end
2 changes: 1 addition & 1 deletion lib/asciinema/file_store/local.ex
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ defmodule Asciinema.FileStore.Local do
conn
|> put_resp_header("content-type", MIME.from_path(path))
|> send_file(200, full_path(path))
|> halt
|> halt()
end

@impl true
Expand Down
2 changes: 1 addition & 1 deletion lib/asciinema/file_store/s3.ex
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ defmodule Asciinema.FileStore.S3 do

@impl true
def open_file(path, function \\ nil) do
response = bucket() |> S3.get_object(base_path() <> path) |> make_request
response = bucket() |> S3.get_object(base_path() <> path) |> make_request()

with {:ok, %{headers: headers, body: body}} <- response do
body =
Expand Down
4 changes: 2 additions & 2 deletions lib/asciinema/streaming.ex
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ defmodule Asciinema.Streaming do
def list_public_live_streams(owner, limit \\ 4) do
owner
|> live_streams_q(limit)
|> where([s], not s.private)
|> where([s], s.visibility == :public)
|> Repo.all()
end

Expand Down Expand Up @@ -85,7 +85,7 @@ defmodule Asciinema.Streaming do
|> cast(attrs, [
:title,
:description,
:private,
:visibility,
:theme_name,
:theme_prefer_original,
:buffer_time,
Expand Down
2 changes: 1 addition & 1 deletion lib/asciinema/streaming/live_stream.ex
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ defmodule Asciinema.Streaming.LiveStream do
schema "live_streams" do
field :public_token, :string
field :producer_token, :string
field :private, :boolean, default: true
field :visibility, Ecto.Enum, values: [:private, :unlisted, :public], default: :unlisted
field :cols, :integer
field :rows, :integer
field :online, :boolean
Expand Down
2 changes: 1 addition & 1 deletion lib/asciinema/streaming/live_stream_server.ex
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
defmodule Asciinema.Streaming.LiveStreamServer do
use GenServer, restart: :transient
use GenServer, restart: :temporary
alias Asciinema.Recordings.Snapshot
alias Asciinema.Streaming.ViewerTracker
alias Asciinema.{Colors, PubSub, Streaming, Vt}
Expand Down
5 changes: 1 addition & 4 deletions lib/asciinema/telemetry.ex
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,7 @@ defmodule Asciinema.Telemetry do
end

def init(_arg) do
children = [
{:telemetry_poller, period: 10_000},
{TelemetryMetricsPrometheus, metrics: metrics()}
]
children = [{:telemetry_poller, period: 10_000}]

Supervisor.init(children, strategy: :one_for_one)
end
Expand Down
32 changes: 5 additions & 27 deletions lib/asciinema_web.ex
Original file line number Diff line number Diff line change
Expand Up @@ -20,46 +20,21 @@ defmodule AsciinemaWeb do
def static_paths, do: ~w(css fonts images js favicon.ico robots.txt)

def controller do
quote do
use Phoenix.Controller, namespace: AsciinemaWeb

import Plug.Conn
import AsciinemaWeb.Gettext
import AsciinemaWeb.Router.Helpers.Extra
import AsciinemaWeb.Auth, only: [require_current_user: 2]
import AsciinemaWeb.Plug.ReturnTo
import AsciinemaWeb.Plug.Authz
alias AsciinemaWeb.Router.Helpers, as: Routes

unquote(verified_routes())

action_fallback AsciinemaWeb.FallbackController

defp clear_main_class(conn, _) do
assign(conn, :main_class, "")
end
end
end

def new_controller do
quote do
use Phoenix.Controller,
formats: [:html, :json, :svg]
formats: [:html, :json, :svg, :xml, :text]

import Plug.Conn
import AsciinemaWeb.Gettext
import AsciinemaWeb.Router.Helpers.Extra
import AsciinemaWeb.Auth, only: [require_current_user: 2]
import AsciinemaWeb.Plug.ReturnTo
import AsciinemaWeb.Plug.Authz
import AsciinemaWeb.Caching

unquote(verified_routes())

action_fallback AsciinemaWeb.FallbackController

defp clear_main_class(conn, _) do
assign(conn, :main_class, "")
end
end
end

Expand Down Expand Up @@ -180,6 +155,9 @@ defmodule AsciinemaWeb do

def json do
quote do
import AsciinemaWeb.ErrorHelpers
import AsciinemaWeb.Router.Helpers.Extra

# Routes generation with the ~p sigil
unquote(verified_routes())
end
Expand Down
4 changes: 2 additions & 2 deletions lib/asciinema_web/auth.ex
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,10 @@ defmodule AsciinemaWeb.Auth do
msg = Keyword.get(opts, :flash, "Please log in first.")

conn
|> save_return_path
|> save_return_path()
|> put_flash(:info, msg)
|> redirect(to: Routes.login_path(conn, :new))
|> halt
|> halt()
end

def require_admin(%Conn{assigns: %{current_user: %User{is_admin: true}}} = conn, _) do
Expand Down
17 changes: 17 additions & 0 deletions lib/asciinema_web/caching.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
defmodule AsciinemaWeb.Caching do
import Plug.Conn

def put_etag(conn, content) do
etag = Crypto.md5(to_string(content))

conn
|> put_resp_header("etag", etag)
|> register_before_send(fn conn ->
if etag in get_req_header(conn, "if-none-match") do
resp(conn, 304, "")
else
conn
end
end)
end
end
3 changes: 2 additions & 1 deletion lib/asciinema_web/controllers/api/live_stream_controller.ex
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ defmodule AsciinemaWeb.Api.LiveStreamController do
use AsciinemaWeb, :controller
import AsciinemaWeb.Auth, only: [get_basic_auth: 1]
alias Asciinema.{Accounts, Streaming}
alias AsciinemaWeb.Router.Helpers.Extra, as: Routes

plug :accepts, ~w(json)
plug :authenticate
Expand All @@ -12,7 +13,7 @@ defmodule AsciinemaWeb.Api.LiveStreamController do
if stream = Streaming.get_live_stream(conn.assigns.current_user, id) do
json(conn, %{
url: url(~p"/s/#{stream}"),
ws_producer_url: Routes.Extra.ws_producer_url(stream)
ws_producer_url: Routes.ws_producer_url(stream)
})
else
conn
Expand Down
Loading

0 comments on commit 3e755d8

Please sign in to comment.