mirror of
https://github.com/outbackdingo/firezone.git
synced 2026-01-27 10:18:54 +00:00
Checkpoint
This commit is contained in:
@@ -1 +1,5 @@
|
||||
/* Main Styles */
|
||||
|
||||
nav.navbar {
|
||||
border-bottom: 1px solid black;
|
||||
}
|
||||
|
||||
@@ -12,6 +12,14 @@ defmodule FgHttp.Devices do
|
||||
Repo.all(from d in Device, where: d.user_id == ^user_id)
|
||||
end
|
||||
|
||||
def list_devices(user_id, with_rules: true) do
|
||||
Repo.all(
|
||||
from d in Device,
|
||||
where: d.user_id == ^user_id,
|
||||
preload: :rules
|
||||
)
|
||||
end
|
||||
|
||||
def get_device!(id), do: Repo.get!(Device, id)
|
||||
|
||||
def get_device!(id, with_rules: true) do
|
||||
|
||||
@@ -9,7 +9,7 @@ defmodule FgHttpWeb.DeviceController do
|
||||
plug FgHttpWeb.Plugs.SessionLoader
|
||||
|
||||
def index(conn, _params) do
|
||||
devices = Devices.list_devices(conn.assigns.session.id)
|
||||
devices = Devices.list_devices(conn.assigns.session.id, with_rules: true)
|
||||
render(conn, "index.html", devices: devices)
|
||||
end
|
||||
|
||||
|
||||
@@ -25,12 +25,12 @@ defmodule FgHttpWeb.UserController do
|
||||
conn
|
||||
|> put_session(:user_id, user.id)
|
||||
|> assign(:session, session)
|
||||
|> put_flash(:info, "User created successfully.")
|
||||
|> put_flash(:info, "Account created successfully.")
|
||||
|> redirect(to: Routes.device_path(conn, :index))
|
||||
|
||||
{:error, %Ecto.Changeset{} = changeset} ->
|
||||
conn
|
||||
|> put_flash(:error, "Error creating user.")
|
||||
|> put_flash(:error, "Error creating account.")
|
||||
|> render("new.html", changeset: changeset)
|
||||
end
|
||||
end
|
||||
@@ -64,12 +64,12 @@ defmodule FgHttpWeb.UserController do
|
||||
|
||||
conn
|
||||
|> assign(:session, session)
|
||||
|> put_flash(:info, "User updated successfully.")
|
||||
|> put_flash(:info, "Account updated successfully.")
|
||||
|> redirect(to: Routes.user_path(conn, :show))
|
||||
|
||||
{:error, changeset} ->
|
||||
conn
|
||||
|> put_flash(:error, "Error updating user.")
|
||||
|> put_flash(:error, "Error updating account.")
|
||||
|> render("edit.html", changeset: changeset)
|
||||
end
|
||||
end
|
||||
@@ -83,12 +83,12 @@ defmodule FgHttpWeb.UserController do
|
||||
conn
|
||||
|> clear_session()
|
||||
|> assign(:session, nil)
|
||||
|> put_flash(:info, "User deleted successfully.")
|
||||
|> put_flash(:info, "Account deleted successfully.")
|
||||
|> redirect(to: "/")
|
||||
|
||||
{:error, changeset} ->
|
||||
conn
|
||||
|> put_flash(:error, "Error deleting User.")
|
||||
|> put_flash(:error, "Error deleting account.")
|
||||
|> render("edit.html", changeset: changeset)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -5,7 +5,7 @@ defmodule FgHttpWeb.NewDeviceLive do
|
||||
|
||||
use Phoenix.LiveView
|
||||
use Phoenix.HTML
|
||||
alias FgHttp.Devices.Device
|
||||
alias FgHttp.{Devices.Device, Util.FgCrypto}
|
||||
alias FgHttpWeb.Router.Helpers, as: Routes
|
||||
|
||||
# Number of seconds before simulating a device connect
|
||||
@@ -14,7 +14,7 @@ defmodule FgHttpWeb.NewDeviceLive do
|
||||
def mount(_params, %{"user_id" => user_id}, socket) do
|
||||
if connected?(socket) do
|
||||
# Send a mock device connect
|
||||
:timer.send_after(@mocked_timer, self(), {:pubkey, "foobar"})
|
||||
:timer.send_after(@mocked_timer, self(), {:pubkey, FgCrypto.rand_string()})
|
||||
end
|
||||
|
||||
device = %Device{user_id: user_id, last_ip: "127.0.0.1"}
|
||||
|
||||
@@ -60,7 +60,7 @@ Endpoint = <%= Application.fetch_env!(:fg_http, :vpn_endpoint) %>
|
||||
<%=
|
||||
link(to: Routes.device_path(@socket, :create, "device[public_key]": @device.public_key),
|
||||
method: :post,
|
||||
class: "button is-success") do %>
|
||||
class: "button is-primary") do %>
|
||||
Verify and Add Device
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
@@ -18,7 +18,9 @@
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<%= submit "Save", class: "button is-primary" %>
|
||||
<div class="control">
|
||||
<%= submit "Save", class: "button is-primary" %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
@@ -4,7 +4,9 @@
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Rules</th>
|
||||
<th>Public key</th>
|
||||
<th>Last IP</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
@@ -12,7 +14,9 @@
|
||||
<%= for device <- @devices do %>
|
||||
<tr>
|
||||
<td><%= device.name %></td>
|
||||
<td><%= link rules_title(device), to: Routes.device_rule_path(@conn, :index, device) %></td>
|
||||
<td><%= device.public_key %></td>
|
||||
<td><%= device.last_ip || "Never connected" %></td>
|
||||
<td>
|
||||
<span><%= link "Show", to: Routes.device_path(@conn, :show, device) %></span>
|
||||
|
|
||||
@@ -25,4 +29,4 @@
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<%= link "New Device", to: Routes.device_path(@conn, :new) %>
|
||||
<%= link "New Device", to: Routes.device_path(@conn, :new), class: "button is-primary" %>
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
<h1>Show Device</h1>
|
||||
<div class="content">
|
||||
<h3>Show Device</h3>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<strong>Name:</strong>
|
||||
<%= @device.name %>
|
||||
</li>
|
||||
<dl>
|
||||
<dt>Name:</dt>
|
||||
<dd><%= @device.name %></dd>
|
||||
|
||||
<li>
|
||||
<strong>Public key:</strong>
|
||||
<%= @device.public_key %>
|
||||
</li>
|
||||
</ul>
|
||||
<dt>Public key:</dt>
|
||||
<dd><%= @device.public_key %></dd>
|
||||
</dl>
|
||||
|
||||
<p>
|
||||
<%= link "Show Rules for This Device", to: Routes.device_rule_path(@conn, :index, @device) %>
|
||||
</p>
|
||||
<p>
|
||||
<%= link "Show Rules for This Device", to: Routes.device_rule_path(@conn, :index, @device) %>
|
||||
</p>
|
||||
|
||||
<p><%= link "Edit", to: Routes.device_path(@conn, :edit, @device) %></p>
|
||||
<p><%= link "Back", to: Routes.device_path(@conn, :index) %></p>
|
||||
<div class="level">
|
||||
<%= link "Back", to: Routes.device_path(@conn, :index), class: "button" %>
|
||||
<%= link "Edit", to: Routes.device_path(@conn, :edit, @device), class: "button is-primary" %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
</head>
|
||||
<body>
|
||||
<%= render "nav.html", assigns %>
|
||||
<%= render "flash.html", assigns %>
|
||||
<section class="section">
|
||||
<%= render "flash.html", assigns %>
|
||||
<div class="container">
|
||||
<%= @inner_content %>
|
||||
</div>
|
||||
|
||||
@@ -1,18 +1,16 @@
|
||||
<%= unless is_nil(get_flash(@conn, :info)) and is_nil(get_flash(@conn, :error)) do %>
|
||||
<section class="section">
|
||||
<div class="container">
|
||||
<div class="notification">
|
||||
<%= if get_flash(@conn, :info) do %>
|
||||
<div class="flash-info">
|
||||
<%= get_flash(@conn, :info) %>
|
||||
</div>
|
||||
<% end %>
|
||||
<%= if get_flash(@conn, :error) do %>
|
||||
<div class="flash-error">
|
||||
<%= get_flash(@conn, :error) %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<div class="container">
|
||||
<div class="notification">
|
||||
<%= if get_flash(@conn, :info) do %>
|
||||
<div class="flash-info">
|
||||
<%= get_flash(@conn, :info) %>
|
||||
</div>
|
||||
<% end %>
|
||||
<%= if get_flash(@conn, :error) do %>
|
||||
<div class="flash-error">
|
||||
<%= get_flash(@conn, :error) %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
@@ -6,23 +6,25 @@
|
||||
</h4>
|
||||
</div>
|
||||
<div class="navbar-menu">
|
||||
<%= if assigns[:session] do %>
|
||||
<div class="navbar-start">
|
||||
<%= link "Devices", to: Routes.device_path(@conn, :index), class: "navbar-item" %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<div class="navbar-end">
|
||||
<div class="navbar-item">
|
||||
<div class="buttons">
|
||||
<%= if assigns[:session] do %>
|
||||
<span>
|
||||
<%= link("Your Account", to: Routes.user_path(@conn, :show)) %>
|
||||
</span>
|
||||
|
|
||||
<span>
|
||||
<%= link("Sign out", to: Routes.session_path(@conn, :delete), method: :delete) %>
|
||||
</span>
|
||||
<% else %>
|
||||
<%= link("Sign in", to: Routes.session_path(@conn, :new)) %>
|
||||
<% end %>
|
||||
<%= if assigns[:session] do %>
|
||||
<div class="navbar-item">
|
||||
<%= link("Your Account", to: Routes.user_path(@conn, :show)) %>
|
||||
</div>
|
||||
</div>
|
||||
<div class="navbar-item">
|
||||
<%= link("Sign out", to: Routes.session_path(@conn, :delete), method: :delete) %>
|
||||
</div>
|
||||
<% else %>
|
||||
<div class="navbar-item">
|
||||
<%= link("Sign in", to: Routes.session_path(@conn, :new)) %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
@@ -63,7 +63,16 @@
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<%= submit "Save", class: "button is-primary" %>
|
||||
<div class="control">
|
||||
<div class="level">
|
||||
<div class="level-left">
|
||||
<%= link "Back", to: Routes.device_rule_path(@conn, :index, @device), class: "button" %>
|
||||
</div>
|
||||
<div class="level-right">
|
||||
<%= submit "Save", class: "button is-primary" %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
<h1>New Rule for Device <%= @device.name %></h1>
|
||||
<h3 class="title is-3">New Rule for Device <%= @device.name %></h3>
|
||||
|
||||
<%= render "form.html", Map.put(assigns, :action, Routes.device_rule_path(@conn, :create, @device)) %>
|
||||
|
||||
<span><%= link "Back", to: Routes.device_rule_path(@conn, :index, @device) %></span>
|
||||
|
||||
@@ -1,38 +1,28 @@
|
||||
<h3 class="title is-3">Show Rule</h1>
|
||||
<div class="content">
|
||||
<h3>Show Rule</h3>
|
||||
|
||||
<ul>
|
||||
<dl>
|
||||
<dt>Action:</dt>
|
||||
<dd><%= @rule.action %></dd>
|
||||
|
||||
<li>
|
||||
<strong>Action:</strong>
|
||||
<%= @rule.action %>
|
||||
</li>
|
||||
<dt>Destination:</dt>
|
||||
<dd><%= @rule.destination %></dd>
|
||||
|
||||
<li>
|
||||
<strong>Destination:</strong>
|
||||
<%= @rule.destination %>
|
||||
</li>
|
||||
<dt>Port:</dt>
|
||||
<dd><%= @rule.port %></dd>
|
||||
|
||||
<li>
|
||||
<strong>Port:</strong>
|
||||
<%= @rule.port %>
|
||||
</li>
|
||||
<dt>Protocol:</dt>
|
||||
<dd><%= @rule.protocol %></dd>
|
||||
|
||||
<li>
|
||||
<strong>Protocol:</strong>
|
||||
<%= @rule.protocol %>
|
||||
</li>
|
||||
<dt>Priority</dt>
|
||||
<dd><%= @rule.priority %></dd>
|
||||
|
||||
<li>
|
||||
<strong>Priority</strong>
|
||||
<%= @rule.priority %>
|
||||
</li>
|
||||
<dt>Enabled:</dt>
|
||||
<dd><%= @rule.enabled %></dd>
|
||||
</dl>
|
||||
|
||||
<li>
|
||||
<strong>Enabled:</strong>
|
||||
<%= @rule.enabled %>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
|
||||
<span><%= link "Edit", to: Routes.rule_path(@conn, :edit, @rule) %></span>
|
||||
<span><%= link "Back", to: Routes.device_rule_path(@conn, :index, @rule.device_id) %></span>
|
||||
<div class="level">
|
||||
<%= link "Edit", to: Routes.rule_path(@conn, :edit, @rule), class: "button is-primary" %>
|
||||
<%= link "Back", to: Routes.device_rule_path(@conn, :index, @rule.device_id), class: "button is-danger" %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
|
||||
<div class="field">
|
||||
<div class="control">
|
||||
<%= submit "Sign in", class: "button is-link" %>
|
||||
<%= submit "Sign in", class: "button is-primary" %>
|
||||
</div>
|
||||
</div>
|
||||
<% end) %>
|
||||
|
||||
@@ -1,34 +1,59 @@
|
||||
<%= form_for @changeset, Routes.user_path(@conn, :update), fn f -> %>
|
||||
<%= if @changeset.action do %>
|
||||
<div>
|
||||
<p>Oops, something went wrong! Please check the errors below.</p>
|
||||
</div>
|
||||
<% end %>
|
||||
<h3 class="title is-3">Edit Account</h3>
|
||||
|
||||
<fieldset id="edit_user" class="ba b--transparent ph0 mh0">
|
||||
<legend class="f4 fw6 ph0 mh0">Edit Account</legend>
|
||||
<div class="mt3">
|
||||
<%= label(f, :email, class: "db fw6 lh-copy f6") %>
|
||||
<%= text_input(f, :email, class: "pa2 input-reset ba bg-transparent hover-bg-black hover-white w-100") %>
|
||||
<%= error_tag f, :email %>
|
||||
</div>
|
||||
<div class="mv3">
|
||||
<%= label(f, :password, class: "db fw6 lh-copy f6") %>
|
||||
<%= password_input(f, :password, class: "pa2 input-reset ba bg-transparent hover-bg-black hover-white w-100") %>
|
||||
<%= error_tag f, :password %>
|
||||
</div>
|
||||
<div class="mv3">
|
||||
<%= label(f, :password_confirmation, class: "db fw6 lh-copy f6") %>
|
||||
<%= password_input(f, :password_confirmation, class: "pa2 input-reset ba bg-transparent hover-bg-black hover-white w-100") %>
|
||||
<%= error_tag f, :password_confirmation %>
|
||||
</div>
|
||||
<div class="mv3">
|
||||
<%= label(f, :current_password, class: "db fw6 lh-copy f6") %>
|
||||
<%= password_input(f, :current_password, class: "pa2 input-reset ba bg-transparent hover-bg-black hover-white w-100") %>
|
||||
<%= error_tag f, :current_password %>
|
||||
</div>
|
||||
</fieldset>
|
||||
<div>
|
||||
<%= submit "Save", class: "b ph3 pv2 input-reset ba b--black bg-transparent grow pointer f6 dib" %>
|
||||
<div class="columns">
|
||||
<div class="column is-4">
|
||||
<%= form_for @changeset, Routes.user_path(@conn, :update), fn f -> %>
|
||||
<%= if @changeset.action do %>
|
||||
<div>
|
||||
<p>Oops, something went wrong! Please check the errors below.</p>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<div class="field">
|
||||
<%= label f, :email, class: "label" %>
|
||||
|
||||
<div class="control">
|
||||
<%= text_input f, :email, class: "input" %>
|
||||
</div>
|
||||
<p class="help">
|
||||
<%= error_tag f, :email %>
|
||||
</p>
|
||||
<div>
|
||||
|
||||
<div class="field">
|
||||
<%= label f, :password, class: "label" %>
|
||||
<div class="control">
|
||||
<%= password_input f, :password, class: "input password" %>
|
||||
</div>
|
||||
<p class="help">
|
||||
<%= error_tag f, :password %>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<%= label f, :password_confirmation, class: "label" %>
|
||||
<div class="control">
|
||||
<%= password_input f, :password_confirmation, class: "input password" %>
|
||||
</div>
|
||||
<p class="help">
|
||||
<%= error_tag f, :password_confirmation %>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<%= label f, :current_password, class: "label" %>
|
||||
<%= password_input f, :current_password, class: "input password" %>
|
||||
|
||||
<p class="help">
|
||||
<%= error_tag f, :current_password %>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<div class="control">
|
||||
<%= submit "Save", class: "button is-primary" %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
|
||||
<div class="field">
|
||||
<div class="control">
|
||||
<%= submit "Sign Up", class: "button is-link" %>
|
||||
<%= submit "Sign Up", class: "button is-primary" %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
@@ -1,15 +1,23 @@
|
||||
<h1>Your Account</h1>
|
||||
<div class="content">
|
||||
<h3>Your Account</h3>
|
||||
|
||||
<dl>
|
||||
<dt>Email</dt>
|
||||
<dd><%= @user.email %></dd>
|
||||
<dl>
|
||||
<dt>
|
||||
<strong>Email</strong>
|
||||
</dt>
|
||||
<dd><%= @user.email %></dd>
|
||||
|
||||
<dt>Last signed in at</dt>
|
||||
<dd><%= @session.last_signed_in_at %></dd>
|
||||
</dl>
|
||||
<dt><strong>Last signed in at</strong></dt>
|
||||
<dd><%= @session.last_signed_in_at %></dd>
|
||||
</dl>
|
||||
|
||||
<%= link("Edit", to: Routes.user_path(@conn, :edit)) %>
|
||||
|
||||
|
|
||||
|
||||
<%= link("Delete your account", to: Routes.user_path(@conn, :delete)) %>
|
||||
<div class="level">
|
||||
<%= link("Edit", to: Routes.user_path(@conn, :edit), class: "button is-primary") %>
|
||||
<%= link "Delete your account",
|
||||
to: Routes.user_path(@conn, :delete),
|
||||
method: :delete,
|
||||
data: [confirm: "Are you sure?"],
|
||||
class: "button is-danger"
|
||||
%>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,3 +1,13 @@
|
||||
defmodule FgHttpWeb.DeviceView do
|
||||
use FgHttpWeb, :view
|
||||
|
||||
alias FgHttp.Devices.Device
|
||||
|
||||
def rules_title(%Device{} = device) do
|
||||
num_rules = length(device.rules)
|
||||
|
||||
"rule"
|
||||
|> Inflex.inflect(num_rules)
|
||||
|> (&("#{num_rules} " <> &1)).()
|
||||
end
|
||||
end
|
||||
|
||||
@@ -53,6 +53,7 @@ defmodule FgHttp.MixProject do
|
||||
{:ecto_sql, "~> 3.1"},
|
||||
{:ecto_enum, "~> 1.4.0"},
|
||||
{:ecto_network, "~> 1.3.0"},
|
||||
{:inflex, "~> 2.0.0"},
|
||||
{:bamboo, "~> 1.5"},
|
||||
{:postgrex, ">= 0.0.0"},
|
||||
{:phoenix_html, "~> 2.11"},
|
||||
|
||||
1
mix.lock
1
mix.lock
@@ -23,6 +23,7 @@
|
||||
"hackney": {:hex, :hackney, "1.16.0", "5096ac8e823e3a441477b2d187e30dd3fff1a82991a806b2003845ce72ce2d84", [:rebar3], [{:certifi, "2.5.2", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "6.0.1", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~>1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "3.3.0", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.6", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm", "3bf0bebbd5d3092a3543b783bf065165fa5d3ad4b899b836810e513064134e18"},
|
||||
"html_entities": {:hex, :html_entities, "0.5.1", "1c9715058b42c35a2ab65edc5b36d0ea66dd083767bef6e3edb57870ef556549", [:mix], [], "hexpm", "30efab070904eb897ff05cd52fa61c1025d7f8ef3a9ca250bc4e6513d16c32de"},
|
||||
"idna": {:hex, :idna, "6.0.1", "1d038fb2e7668ce41fbf681d2c45902e52b3cb9e9c77b55334353b222c2ee50c", [:rebar3], [{:unicode_util_compat, "0.5.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "a02c8a1c4fd601215bb0b0324c8a6986749f807ce35f25449ec9e69758708122"},
|
||||
"inflex": {:hex, :inflex, "2.0.0", "db69d542b8fdb23ac667f9bc0c2395a3983fa2da6ae2efa7ab5dc541928f7a75", [:mix], [], "hexpm", "c018852409bd48b03ad96ed53594186bc074bdd1519043a0ad1fa5697aac4399"},
|
||||
"jason": {:hex, :jason, "1.2.1", "12b22825e22f468c02eb3e4b9985f3d0cb8dc40b9bd704730efa11abd2708c44", [:mix], [{:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "b659b8571deedf60f79c5a608e15414085fa141344e2716fbd6988a084b5f993"},
|
||||
"metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"},
|
||||
"mime": {:hex, :mime, "1.3.1", "30ce04ab3175b6ad0bdce0035cba77bba68b813d523d1aac73d9781b4d193cf8", [:mix], [], "hexpm", "6cbe761d6a0ca5a31a0931bf4c63204bceb64538e664a8ecf784a9a6f3b875f1"},
|
||||
|
||||
Reference in New Issue
Block a user