Compare commits
49
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
eab0d0e097 | ||
|
|
dd33c1eb64 | ||
|
|
f408734070 | ||
|
|
6163a43127 | ||
|
|
fee202137c | ||
|
|
edbee59f23 | ||
|
|
d5cf0cac2b | ||
|
|
10f907e9f9 | ||
|
|
8e309e5a6c | ||
|
|
28af6df793 | ||
|
|
fb90029bc7 | ||
|
|
54d5dd5c39 | ||
|
|
4fcf5489da | ||
|
|
94451e37d8 | ||
|
|
97aa091b9a | ||
|
|
106ae8398e | ||
|
|
5a0995b991 | ||
|
|
b76d005a22 | ||
|
|
76c7bd4a34 | ||
|
|
dbe75a5065 | ||
|
|
20a0b45954 | ||
|
|
bf50e4264d | ||
|
|
82e4d19e6c | ||
|
|
f67e8cf6f9 | ||
|
|
dd609b5d84 | ||
|
|
bec57794fa | ||
|
|
5820652ac1 | ||
|
|
de365b36ad | ||
|
|
24a1a91824 | ||
|
|
56852f43be | ||
|
|
b1d4455cb8 | ||
|
|
33272ee23d | ||
|
|
1ecb497199 | ||
|
|
ec4661fe44 | ||
|
|
8e6cbc647e | ||
|
|
3f424a41c1 | ||
|
|
9b2da2dbf1 | ||
|
|
ae8cee8ccf | ||
|
|
bca77b0ff6 | ||
|
|
8121ea2cf0 | ||
|
|
dd089f13f9 | ||
|
|
1d0b8cc4d5 | ||
|
|
8f4672b516 | ||
|
|
2ddccce85d | ||
|
|
2fa19381dc | ||
|
|
9b18d5186d | ||
|
|
8b7073145d | ||
|
|
b4eb5c7f2f | ||
|
|
d19fe38aee |
No files matched your search
@@ -0,0 +1,12 @@
|
||||
name: Fly Deploy
|
||||
on: [push]
|
||||
env:
|
||||
FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}
|
||||
jobs:
|
||||
deploy:
|
||||
name: Deploy to fly.io
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: superfly/flyctl-actions/setup-flyctl@master
|
||||
- run: flyctl deploy --remote-only
|
||||
+1
-1
@@ -34,7 +34,7 @@ RUN mix phx.digest
|
||||
RUN mix do compile, release
|
||||
|
||||
# prepare release image
|
||||
FROM alpine:3.9 AS app
|
||||
FROM alpine AS app
|
||||
RUN apk add --no-cache openssl ncurses-libs libstdc++
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
@@ -3,5 +3,5 @@ image:
|
||||
docker build -t atechnohazard/katbin-elixir .
|
||||
|
||||
.PHONY: push
|
||||
push:
|
||||
push: image
|
||||
docker push atechnohazard/katbin-elixir
|
||||
@@ -1,4 +1,4 @@
|
||||
# Ketbin
|
||||
# Katbin
|
||||
|
||||
To start your Phoenix server:
|
||||
|
||||
@@ -11,7 +11,37 @@ To start your Phoenix server:
|
||||
|
||||
Now you can visit [`localhost:4000`](http://localhost:4000) from your browser.
|
||||
|
||||
Ready to run in production? Please [check our deployment guides](https://hexdocs.pm/phoenix/deployment.html).
|
||||
# Self hosting
|
||||
|
||||
We recommend using our [official docker image](https://hub.docker.com/r/atechnohazard/katbin-elixir). If you wish to build your own docker image, the provided Dockerfile should work out of the box. If you run into any problems, please open an issue.
|
||||
|
||||
## Populating the environment
|
||||
Copy the provided `sample.env` file to `.env`
|
||||
```sh
|
||||
cp sample.env .env
|
||||
```
|
||||
|
||||
Fill in this new file with the required environment variables.
|
||||
|
||||
## Using the official docker image
|
||||
```sh
|
||||
docker run --env-file .env atechnohazard/katbin-elixir
|
||||
```
|
||||
|
||||
## Building the docker image
|
||||
```sh
|
||||
git clone https://github.com/SphericalKat/katbin
|
||||
cd katbin
|
||||
docker build -t <username>/katbin .
|
||||
```
|
||||
|
||||
## Running the built docker image
|
||||
```sh
|
||||
docker run --env-file .env <username>/katbin
|
||||
```
|
||||
|
||||
For other methods of self hosting, please check the [official Phoenix deployment guides](https://hexdocs.pm/phoenix/deployment.html).
|
||||
|
||||
|
||||
## Learn more
|
||||
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@ fs.copySync("static/", "../priv/static/");
|
||||
console.log("[build.js] [info] Copying static files from static/");
|
||||
|
||||
if (!productionBuild) {
|
||||
console.log("[build.js] [info] Starting to watching assets for changes");
|
||||
console.log("[build.js] [info] Starting to watch assets for changes");
|
||||
} else {
|
||||
console.log("[build.js] [info] Building assets in production mode");
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
@import "tailwindcss/components";
|
||||
@import "tailwindcss/utilities";
|
||||
@import "./highlight.css";
|
||||
@import "./markdown.css";
|
||||
|
||||
@font-face {
|
||||
font-family: "JetBrains Mono";
|
||||
@@ -18,14 +19,61 @@
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
@layer base {
|
||||
h1 {
|
||||
font-size: 2em;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 1.5em;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 1.17em;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
h5 {
|
||||
font-size: 0.83em;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
h6 {
|
||||
font-size: 0.67em;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
h1,
|
||||
h2,
|
||||
h3 {
|
||||
margin-top: 20px;
|
||||
margin-bottom: 10px
|
||||
}
|
||||
|
||||
img {
|
||||
display: inline;
|
||||
}
|
||||
}
|
||||
|
||||
html,
|
||||
body {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #ff9800;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: #ff9800;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
header {
|
||||
@@ -47,6 +95,21 @@ textarea {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-corner,
|
||||
::-webkit-scrollbar-track {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
border-radius: 8px;
|
||||
@apply bg-amber;
|
||||
}
|
||||
|
||||
.alert {
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
|
||||
@@ -0,0 +1,179 @@
|
||||
.markdown p {
|
||||
font-family: sans-serif;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.markdown p > * {
|
||||
font-family: sans-serif;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.markdown h1,
|
||||
h2,
|
||||
h3 {
|
||||
margin-top: 20px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.markdown h1 {
|
||||
font-size: 2em;
|
||||
@apply text-amber;
|
||||
}
|
||||
|
||||
.markdown h2 {
|
||||
font-size: 1.5em;
|
||||
@apply text-amber;
|
||||
}
|
||||
|
||||
.markdown h3 {
|
||||
font-size: 1.17em;
|
||||
@apply text-amber;
|
||||
}
|
||||
|
||||
.markdown h4 {
|
||||
font-size: 1em;
|
||||
@apply text-amber;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.markdown h5 {
|
||||
font-size: 0.83em;
|
||||
@apply text-amber;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.markdown h6 {
|
||||
font-size: 0.75em;
|
||||
@apply text-amber;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.markdown blockquote {
|
||||
padding: 0 1em;
|
||||
margin: 0 0 20px;
|
||||
font-size: 17.5px;
|
||||
border-left: 4px solid #8b949e;
|
||||
}
|
||||
|
||||
.markdown img {
|
||||
max-width: 35%;
|
||||
vertical-align: middle;
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.markdown table {
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
margin-bottom: 20px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
tbody > tr:nth-child(odd) > td,
|
||||
.table-striped > tbody > tr:nth-child(odd) > th {
|
||||
background-color: #1b1b1b;
|
||||
}
|
||||
.table-striped > tbody > tr:nth-child(odd) > td,
|
||||
.table-striped > tbody > tr:nth-child(odd) > th {
|
||||
background-color: #1b1b1b;
|
||||
}
|
||||
table > thead > tr > th,
|
||||
table > tbody > tr > th,
|
||||
table > tfoot > tr > th,
|
||||
table > thead > tr > td,
|
||||
table > tbody > tr > td,
|
||||
table > tfoot > tr > td {
|
||||
padding: 8px;
|
||||
line-height: 1.42857143;
|
||||
vertical-align: top;
|
||||
border: 1px solid #3b434b;
|
||||
}
|
||||
|
||||
.markdown hr {
|
||||
margin-top: 20px;
|
||||
margin-bottom: 20px;
|
||||
border: 0;
|
||||
border-top: 1px solid #3b434b;
|
||||
}
|
||||
|
||||
.markdown {
|
||||
/* border: 1px solid #3b434b; */
|
||||
border-radius: 6px;
|
||||
padding-right: 32px;
|
||||
padding-left: 32px;
|
||||
}
|
||||
|
||||
.markdown pre {
|
||||
padding: 12px;
|
||||
overflow: auto;
|
||||
font-size: 85%;
|
||||
line-height: 1.45;
|
||||
background-color: #1b1b1b;
|
||||
border-radius: 6px;
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
.markdown code pre tt {
|
||||
font-family: "JetbrainsMono", SFMono-Regular, Consolas, Liberation Mono, Menlo,
|
||||
monospace;
|
||||
}
|
||||
|
||||
.markdown blockquote > :last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.markdown blockquote,
|
||||
.markdown p,
|
||||
.markdown ol,
|
||||
.markdown pre,
|
||||
.markdown table,
|
||||
.markdown ul {
|
||||
margin-top: 0;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
h1,
|
||||
h2 {
|
||||
padding-bottom: 0.3em;
|
||||
border-bottom: 1px solid #3b434b;
|
||||
}
|
||||
|
||||
.markdown li {
|
||||
display: list-item;
|
||||
text-align: -webkit-match-parent;
|
||||
font-family: sans-serif;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.markdown ol {
|
||||
list-style-type: decimal;
|
||||
}
|
||||
|
||||
.markdown ol,
|
||||
ul {
|
||||
padding: 0;
|
||||
margin-left: 40px;
|
||||
}
|
||||
|
||||
.markdown strong {
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
.markdown code.inline {
|
||||
font-family: "JetBrains Mono", monospace;
|
||||
background-color: rgb(240 246 252 / 15%);
|
||||
font-weight: bold;
|
||||
border-radius: 4px;
|
||||
font-size: 80%;
|
||||
margin: 0;
|
||||
padding: 0.1em 0.4em;
|
||||
}
|
||||
|
||||
.markdown ul {
|
||||
list-style: disc;
|
||||
}
|
||||
.markdown ol {
|
||||
list-style: decimal;
|
||||
}
|
||||
.markdown ul, ol {
|
||||
padding: 0;
|
||||
margin-left: 40px;
|
||||
}
|
||||
Generated
+638
-697
File diff suppressed because it is too large.
Load diff
@@ -3,6 +3,7 @@ module.exports = {
|
||||
"../lib/**/*.ex",
|
||||
"../lib/**/*.leex",
|
||||
"../lib/**/*.eex",
|
||||
"../lib/**/*.heex",
|
||||
"./js/**/*.js",
|
||||
],
|
||||
darkMode: false, // or 'media' or 'class'
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
# is restricted to this project.
|
||||
|
||||
# General application configuration
|
||||
use Mix.Config
|
||||
import Config
|
||||
|
||||
config :ketbin,
|
||||
ecto_repos: [Ketbin.Repo]
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
use Mix.Config
|
||||
import Config
|
||||
|
||||
# For development, we disable any cache and enable
|
||||
# debugging and code reloading.
|
||||
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
use Mix.Config
|
||||
import Config
|
||||
|
||||
# For production, don't forget to configure the url host
|
||||
# to something meaningful, Phoenix uses this information
|
||||
@@ -10,7 +10,7 @@ use Mix.Config
|
||||
# which you should run after static files are built and
|
||||
# before starting your production server.
|
||||
config :ketbin, KetbinWeb.Endpoint,
|
||||
url: [host: "dev.katb.in", port: 80],
|
||||
url: [host: "katb.in", port: 80],
|
||||
cache_static_manifest: "priv/static/cache_manifest.json"
|
||||
|
||||
# Do not print debug messages in production
|
||||
|
||||
+8
-5
@@ -12,12 +12,12 @@ database_url =
|
||||
"""
|
||||
|
||||
config :ketbin, Ketbin.Repo,
|
||||
ssl: true,
|
||||
verify: :verify_peer,
|
||||
ssl: false,
|
||||
# verify: :verify_peer,
|
||||
socket_options: [:inet6],
|
||||
url: database_url,
|
||||
pool_size: String.to_integer(System.get_env("POOL_SIZE") || "10"),
|
||||
cacertfile: "priv/cert.pem"
|
||||
|
||||
pool_size: String.to_integer(System.get_env("POOL_SIZE") || "10")
|
||||
# cacertfile: "priv/cert.pem"
|
||||
secret_key_base =
|
||||
System.get_env("SECRET_KEY_BASE") ||
|
||||
raise """
|
||||
@@ -38,11 +38,13 @@ config :ketbin, KetbinWeb.Endpoint,
|
||||
raise """
|
||||
environment variable SWOOSH_SMTP_RELAY is missing.
|
||||
"""
|
||||
|
||||
username =
|
||||
System.get_env("SWOOSH_USERNAME") ||
|
||||
raise """
|
||||
environment variable SWOOSH_USERNAME is missing.
|
||||
"""
|
||||
|
||||
password =
|
||||
System.get_env("SWOOSH_PASSWORD") ||
|
||||
raise """
|
||||
@@ -58,6 +60,7 @@ config :ketbin, KetbinWeb.Endpoint,
|
||||
tls: :always,
|
||||
auth: :always,
|
||||
port: 587
|
||||
|
||||
# ## Using releases (Elixir v1.9+)
|
||||
#
|
||||
# If you are doing OTP releases, you need to instruct Phoenix
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
# fly.toml file generated for katbin on 2022-05-06T17:46:21+05:30
|
||||
|
||||
app = "katbin"
|
||||
|
||||
kill_signal = "SIGTERM"
|
||||
kill_timeout = 5
|
||||
processes = []
|
||||
|
||||
# [deploy]
|
||||
# release_command = "/app/bin/migrate"
|
||||
|
||||
[env]
|
||||
PHX_HOST = "katbin.fly.dev"
|
||||
PORT = "8080"
|
||||
|
||||
[experimental]
|
||||
allowed_public_ports = []
|
||||
auto_rollback = true
|
||||
|
||||
[[services]]
|
||||
http_checks = []
|
||||
internal_port = 8080
|
||||
processes = ["app"]
|
||||
protocol = "tcp"
|
||||
script_checks = []
|
||||
|
||||
[services.concurrency]
|
||||
hard_limit = 25
|
||||
soft_limit = 20
|
||||
type = "connections"
|
||||
|
||||
[[services.ports]]
|
||||
force_https = true
|
||||
handlers = ["http"]
|
||||
port = 80
|
||||
|
||||
[[services.ports]]
|
||||
handlers = ["tls", "http"]
|
||||
port = 443
|
||||
|
||||
[[services.tcp_checks]]
|
||||
grace_period = "1s"
|
||||
interval = "15s"
|
||||
restart_limit = 0
|
||||
timeout = "2s"
|
||||
@@ -1,6 +1,7 @@
|
||||
defmodule Ketbin.Pastes.Paste do
|
||||
use Ecto.Schema
|
||||
import Ecto.Changeset
|
||||
@derive {Jason.Encoder, only: [:content, :is_url, :belongs_to]}
|
||||
|
||||
@primary_key {:id, :string, autogenerate: false}
|
||||
@derive {Phoenix.Param, key: :id}
|
||||
@@ -15,5 +16,6 @@ defmodule Ketbin.Pastes.Paste do
|
||||
paste
|
||||
|> cast(attrs, [:is_url, :content, :id, :belongs_to])
|
||||
|> validate_required([:is_url, :content])
|
||||
|> unique_constraint(:id, name: :pastes_pkey)
|
||||
end
|
||||
end
|
||||
@@ -13,23 +13,21 @@ defmodule Ketbin.Pastes.Utils do
|
||||
|
||||
def generate_key(length \\ 10) do
|
||||
random = Enum.random([0, 1])
|
||||
Enum.map(0..length, fn i -> if Integer.mod(i, 2) == random, do: rand_consonant(), else: rand_vowel() end)
|
||||
|> List.to_string
|
||||
|
||||
Enum.map(0..length, fn i ->
|
||||
if Integer.mod(i, 2) == random, do: rand_consonant(), else: rand_vowel()
|
||||
end)
|
||||
|> List.to_string()
|
||||
end
|
||||
|
||||
def is_url?(url) do
|
||||
try do
|
||||
uri = URI.parse(url)
|
||||
uri.scheme != nil && uri.host =~ "." && Enum.member?(["https", "http", "mailto"], uri.scheme) && !(uri.host =~ "katb.in")
|
||||
|
||||
uri.scheme != nil && uri.host =~ "." &&
|
||||
Enum.member?(["https", "http", "mailto"], uri.scheme) && !(uri.host =~ "katb.in")
|
||||
rescue
|
||||
FunctionClauseError -> false
|
||||
end
|
||||
end
|
||||
|
||||
def is_valid_name?(name) do
|
||||
case name do
|
||||
x when x in ["pastes", "users"] -> false
|
||||
_ -> Regex.match?(~r/^[a-zA-Z0-9_]*$/, name)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,45 @@
|
||||
defmodule KetbinWeb.Api.PasteController do
|
||||
use KetbinWeb, :controller
|
||||
|
||||
alias Ketbin.Pastes
|
||||
alias Ketbin.Pastes.Utils
|
||||
|
||||
def show(conn, %{"id" => id}) do
|
||||
[head | _tail] = String.split(id, ".")
|
||||
|
||||
# fetch paste from db
|
||||
paste = Pastes.get_paste!(head)
|
||||
render(conn, "paste.json", paste: paste)
|
||||
end
|
||||
|
||||
def create(%{assigns: %{current_user: current_user}} = conn, %{"paste" => paste_params}) do
|
||||
# generate phonetic key
|
||||
id = Utils.generate_key()
|
||||
|
||||
# check if content is a url
|
||||
is_url =
|
||||
Map.get(paste_params, "content")
|
||||
|> Utils.is_url?()
|
||||
|
||||
# put id and is_url values into changeset
|
||||
paste_params =
|
||||
Map.put(paste_params, "id", id)
|
||||
|> Map.put("is_url", is_url)
|
||||
|> Map.put("belongs_to", current_user && current_user.id)
|
||||
|
||||
# attempt to create a paste
|
||||
case Pastes.create_paste(paste_params) do
|
||||
# all good
|
||||
{:ok, paste} ->
|
||||
conn
|
||||
|> put_status(:created)
|
||||
|> render("paste.json", paste: paste)
|
||||
|
||||
# something went wrong, bail
|
||||
{:error, %Ecto.Changeset{} = _changeset} ->
|
||||
conn
|
||||
|> put_status(:internal_server_error)
|
||||
|> render("error.json")
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -16,21 +16,40 @@ defmodule KetbinWeb.PageController do
|
||||
[head | tail] = String.split(id, ".")
|
||||
|
||||
# fetch paste from db
|
||||
paste = Pastes.get_paste!(head)
|
||||
paste =
|
||||
try do
|
||||
Pastes.get_paste!(head)
|
||||
rescue
|
||||
Ecto.NoResultsError ->
|
||||
Pastes.get_paste!(id)
|
||||
end
|
||||
|
||||
# paste is a url, redirect
|
||||
# regular paste, show content
|
||||
if paste.is_url do
|
||||
redirect(conn, external: paste.content)
|
||||
redirect(conn,
|
||||
external: paste.content |> String.replace("\r", "") |> String.replace("\n", "")
|
||||
)
|
||||
else
|
||||
render(conn, "show.html", paste: paste, show_edit: show_edit, extension: List.first(tail) || "")
|
||||
render(conn, "show.html",
|
||||
paste: paste,
|
||||
show_edit: show_edit,
|
||||
extension: List.first(tail) || "",
|
||||
page_title: paste.id
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
def showlink(%{assigns: %{show_edit: show_edit}} = conn, %{"id" => id}) do
|
||||
[head | tail] = String.split(id, ".")
|
||||
paste = Pastes.get_paste!(head)
|
||||
render(conn, "show.html", paste: paste, show_edit: show_edit, extension: (if tail == [], do: "", else: tail))
|
||||
|
||||
render(conn, "shorten.html",
|
||||
paste: paste,
|
||||
show_edit: show_edit,
|
||||
extension: if(tail == [], do: "", else: tail),
|
||||
page_title: paste.id
|
||||
)
|
||||
end
|
||||
|
||||
def raw(conn, %{"id" => id}) do
|
||||
@@ -39,47 +58,11 @@ defmodule KetbinWeb.PageController do
|
||||
end
|
||||
|
||||
def create(%{assigns: %{current_user: current_user}} = conn, %{"paste" => paste_params}) do
|
||||
# generate phonetic key
|
||||
id = Utils.generate_key()
|
||||
|
||||
# check if content is a url
|
||||
is_url =
|
||||
Map.get(paste_params, "content")
|
||||
|> Utils.is_url?()
|
||||
|
||||
# put id and is_url values into changeset
|
||||
paste_params =
|
||||
Map.put(paste_params, "id", id)
|
||||
|> Map.put("is_url", is_url)
|
||||
|> Map.put("belongs_to", current_user && current_user.id)
|
||||
|
||||
# attempt to create a paste
|
||||
case Pastes.create_paste(paste_params) do
|
||||
# all good, redirect
|
||||
{:ok, paste} ->
|
||||
unless is_url do
|
||||
conn
|
||||
# is a regular paste, take to regular route
|
||||
|> redirect(to: Routes.page_path(conn, :show, paste))
|
||||
else
|
||||
conn
|
||||
# is a url, take to route with /v/ prefix
|
||||
|> redirect(to: Routes.page_path(conn, :showlink, paste))
|
||||
end
|
||||
|
||||
# something went wrong, bail
|
||||
{:error, %Ecto.Changeset{} = changeset} ->
|
||||
render(conn, "index.html", changeset: changeset)
|
||||
end
|
||||
end
|
||||
|
||||
def create_custom(%{assigns: %{current_user: current_user}} = conn, %{"paste" => paste_params}) do
|
||||
# Get ID from params
|
||||
id = Map.get(paste_params, "id")
|
||||
|
||||
# todo: put_flash and preserve paste content
|
||||
if not Utils.is_valid_name?(id) do
|
||||
|
||||
# if custom url exists, use it as id, else generate phonetic id
|
||||
id =
|
||||
case Map.get(paste_params, "custom_url", "") do
|
||||
custom_url when custom_url != "" -> custom_url
|
||||
_ -> Utils.generate_key()
|
||||
end
|
||||
|
||||
# check if content is a url
|
||||
@@ -109,9 +92,15 @@ defmodule KetbinWeb.PageController do
|
||||
|
||||
# something went wrong, bail
|
||||
{:error, %Ecto.Changeset{} = changeset} ->
|
||||
case changeset.errors[:id] do
|
||||
{"has already been taken", _} ->
|
||||
render(conn, "index.html", changeset: changeset, already_taken: true)
|
||||
|
||||
_ ->
|
||||
render(conn, "index.html", changeset: changeset)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def edit(conn, %{"id" => id}) do
|
||||
paste = Pastes.get_paste!(id)
|
||||
|
||||
@@ -1,63 +0,0 @@
|
||||
defmodule KetbinWeb.PasteController do
|
||||
use KetbinWeb, :controller
|
||||
|
||||
alias Ketbin.Pastes
|
||||
alias Ketbin.Pastes.Paste
|
||||
|
||||
def index(conn, _params) do
|
||||
pastes = Pastes.list_pastes()
|
||||
render(conn, "index.html", pastes: pastes)
|
||||
end
|
||||
|
||||
def new(conn, _params) do
|
||||
changeset = Pastes.change_paste(%Paste{})
|
||||
render(conn, "new.html", changeset: changeset)
|
||||
end
|
||||
|
||||
def create(conn, %{"paste" => paste_params}) do
|
||||
# paste_params = Map.put(paste_params, "id", s)
|
||||
case Pastes.create_paste(paste_params) do
|
||||
{:ok, paste} ->
|
||||
conn
|
||||
|> put_flash(:info, "Paste created successfully.")
|
||||
|> redirect(to: Routes.paste_path(conn, :show, paste))
|
||||
|
||||
{:error, %Ecto.Changeset{} = changeset} ->
|
||||
render(conn, "new.html", changeset: changeset)
|
||||
end
|
||||
end
|
||||
|
||||
def show(conn, %{"id" => id}) do
|
||||
paste = Pastes.get_paste!(id)
|
||||
render(conn, "show.html", paste: paste)
|
||||
end
|
||||
|
||||
def edit(conn, %{"id" => id}) do
|
||||
paste = Pastes.get_paste!(id)
|
||||
changeset = Pastes.change_paste(paste)
|
||||
render(conn, "edit.html", paste: paste, changeset: changeset)
|
||||
end
|
||||
|
||||
def update(conn, %{"id" => id, "paste" => paste_params}) do
|
||||
paste = Pastes.get_paste!(id)
|
||||
|
||||
case Pastes.update_paste(paste, paste_params) do
|
||||
{:ok, paste} ->
|
||||
conn
|
||||
|> put_flash(:info, "Paste updated successfully.")
|
||||
|> redirect(to: Routes.paste_path(conn, :show, paste))
|
||||
|
||||
{:error, %Ecto.Changeset{} = changeset} ->
|
||||
render(conn, "edit.html", paste: paste, changeset: changeset)
|
||||
end
|
||||
end
|
||||
|
||||
def delete(conn, %{"id" => id}) do
|
||||
paste = Pastes.get_paste!(id)
|
||||
{:ok, _paste} = Pastes.delete_paste(paste)
|
||||
|
||||
conn
|
||||
|> put_flash(:info, "Paste deleted successfully.")
|
||||
|> redirect(to: Routes.paste_path(conn, :index))
|
||||
end
|
||||
end
|
||||
@@ -98,7 +98,15 @@ defmodule KetbinWeb.UserAuth do
|
||||
|
||||
def owns_paste(%{params: %{"id" => id}, assigns: %{current_user: user}} = conn, _params) do
|
||||
[head | _tail] = String.split(id, ".")
|
||||
paste = Pastes.get_paste!(head)
|
||||
|
||||
paste =
|
||||
try do
|
||||
Pastes.get_paste!(head)
|
||||
rescue
|
||||
Ecto.NoResultsError ->
|
||||
Pastes.get_paste!(id)
|
||||
end
|
||||
|
||||
assign(conn, :show_edit, (user && user.id == paste.belongs_to) || false)
|
||||
end
|
||||
|
||||
@@ -106,6 +114,7 @@ defmodule KetbinWeb.UserAuth do
|
||||
[head | _tail] = String.split(id, ".")
|
||||
paste = Pastes.get_paste!(head)
|
||||
allow_edit = (user && user.id == paste.belongs_to) || false
|
||||
|
||||
unless allow_edit do
|
||||
conn
|
||||
|> put_flash(:error, "You don't own this paste!")
|
||||
|
||||
@@ -22,5 +22,7 @@ defmodule KetbinWeb.UserSessionController do
|
||||
conn
|
||||
|> put_flash(:info, "Logged out successfully.")
|
||||
|> UserAuth.log_out_user()
|
||||
|
||||
conn
|
||||
end
|
||||
end
|
||||
@@ -45,6 +45,8 @@ defmodule KetbinWeb.UserSettingsController do
|
||||
|> put_session(:user_return_to, Routes.user_settings_path(conn, :edit))
|
||||
|> UserAuth.log_in_user(user)
|
||||
|
||||
conn
|
||||
|
||||
{:error, changeset} ->
|
||||
render(conn, "edit.html", password_changeset: changeset)
|
||||
end
|
||||
|
||||
@@ -44,11 +44,13 @@ defmodule KetbinWeb.Endpoint do
|
||||
|
||||
plug Plug.Parsers,
|
||||
parsers: [:urlencoded, :multipart, :json],
|
||||
length: 10_000_000,
|
||||
pass: ["*/*"],
|
||||
json_decoder: Phoenix.json_library()
|
||||
|
||||
plug Plug.MethodOverride
|
||||
plug Plug.Head
|
||||
plug Plug.Session, @session_options
|
||||
plug CORSPlug
|
||||
plug KetbinWeb.Router
|
||||
end
|
||||
@@ -14,6 +14,8 @@ defmodule KetbinWeb.Router do
|
||||
|
||||
pipeline :api do
|
||||
plug :accepts, ["json"]
|
||||
plug :fetch_session
|
||||
plug :fetch_current_user
|
||||
end
|
||||
|
||||
scope "/", KetbinWeb do
|
||||
@@ -42,6 +44,12 @@ defmodule KetbinWeb.Router do
|
||||
put "/:id", PageController, :update
|
||||
end
|
||||
|
||||
scope "/api", KetbinWeb.Api, as: :api do
|
||||
pipe_through :api
|
||||
|
||||
resources "/paste", PasteController, only: [:show, :index, :create]
|
||||
end
|
||||
|
||||
# Other scopes may use custom stacks.
|
||||
# scope "/api", KetbinWeb do
|
||||
# pipe_through :api
|
||||
@@ -96,6 +104,5 @@ defmodule KetbinWeb.Router do
|
||||
post "/users/confirm", UserConfirmationController, :create
|
||||
get "/users/confirm/:token", UserConfirmationController, :confirm
|
||||
|
||||
resources "/pastes", PasteController
|
||||
end
|
||||
end
|
||||
@@ -1,10 +0,0 @@
|
||||
<ul>
|
||||
<%= if @current_user do %>
|
||||
<li><%= @current_user.email %></li>
|
||||
<li><%= link "Settings", to: Routes.user_settings_path(@conn, :edit) %></li>
|
||||
<li><%= link "Log out", to: Routes.user_session_path(@conn, :delete), method: :delete %></li>
|
||||
<% else %>
|
||||
<li><%= link "Register", to: Routes.user_registration_path(@conn, :new) %></li>
|
||||
<li><%= link "Log in", to: Routes.user_session_path(@conn, :new) %></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
@@ -0,0 +1,10 @@
|
||||
<ul>
|
||||
<%= if @current_user do %>
|
||||
<li><%= @current_user.email %></li>
|
||||
<li><%= link "Settings", to: Routes.user_settings_path(@conn, :edit) %></li>
|
||||
<li><%= link "Log out", to: Routes.user_session_path(@conn, :delete), method: :delete %></li>
|
||||
<% else %>
|
||||
<li><%= link "Register", to: Routes.user_registration_path(@conn, :new) %></li>
|
||||
<li><%= link "Log in", to: Routes.user_session_path(@conn, :new) %></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
@@ -1,47 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||
<title>Katbin</title>
|
||||
<link rel="stylesheet" href="<%= Routes.static_path(@conn, "/assets/app.css") %>"/>
|
||||
<script defer type="text/javascript" src="<%= Routes.static_path(@conn, "/assets/app.js") %>"></script>
|
||||
</head>
|
||||
<body class="flex flex-col ">
|
||||
<header class="flex w-full justify-between items-center py-3 px-6">
|
||||
<a href="<%= Routes.page_path(@conn, :index) %>">
|
||||
<span class="font-semibold text-xl tracking-tight">
|
||||
<span class="text-amber text-xl"><Kat</span>bin/>
|
||||
</span>
|
||||
</a>
|
||||
|
||||
<nav role="navigation">
|
||||
<ul>
|
||||
<%= if function_exported?(Routes, :live_dashboard_path, 2) do %>
|
||||
<li>
|
||||
<%# <%= link "LiveDashboard", to: Routes.live_dashboard_path(@conn, :home) %>
|
||||
</li>
|
||||
<% end %>
|
||||
</ul>
|
||||
<%= render "_user_menu.html", assigns %>
|
||||
</nav>
|
||||
|
||||
</header>
|
||||
<main class="flex flex-col w-full h-full max-h-full overflow-hidden bg-light-grey" role="main">
|
||||
<p class="alert alert-info" role="alert"><%= get_flash(@conn, :info) %></p>
|
||||
<p class="alert alert-danger" role="alert"><%= get_flash(@conn, :error) %></p>
|
||||
<%= @inner_content %>
|
||||
</main>
|
||||
<footer class="font-bold">
|
||||
<div class="flex px-4 py-1 text-xs sm:text-base justify-between text-amber" style="background: #1a1a1a; font-family: JetbrainsMono">
|
||||
<a href="https://sphericalk.at">
|
||||
© <%= DateTime.utc_now().year %> SphericalKat
|
||||
</a>
|
||||
<a href="https://github.com/sphericalkat/katbin-elixir">
|
||||
Fork me!
|
||||
</a>
|
||||
</div>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,100 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||
<%= if Map.has_key?(assigns, :page_title) do %>
|
||||
<title>Katbin - <%= @page_title %></title>
|
||||
<% else %>
|
||||
<title>Katbin</title>
|
||||
<% end %>
|
||||
<title itemprop="name">Katbin</title>
|
||||
|
||||
<meta property="og:type" content="object">
|
||||
<meta property="og:title" content="Katbin">
|
||||
<meta property="og:image" content="/favicon.ico">
|
||||
|
||||
<meta name="twitter:title" content="Katbin">
|
||||
<meta itemprop="name" content="Katbin">
|
||||
<meta name="application-name" content="Katbin">
|
||||
<meta property="og:site_name" content="Katbin">
|
||||
<meta name="theme-color" content="#1a1a1a">
|
||||
<meta property="og:locale" content="en">
|
||||
<meta name="language" content="en">
|
||||
<meta name="twitter:card" content="summary">
|
||||
<meta name="twitter:site" content="@Spherical_Kat">
|
||||
<meta name="twitter:image" content="/favicon.ico">
|
||||
|
||||
<meta name="robots" content="index,follow">
|
||||
<meta name="googlebot" content="index,follow">
|
||||
<meta name="keywords" content="paste,pastebin,url,urlshortener,url-shortener,code,programming,bin,cat,kat,paste,share,save,login">
|
||||
<meta name="coverage" content="Worldwide">
|
||||
<meta name="distribution" content="Global">
|
||||
<meta name="HandheldFriendly" content="True">
|
||||
<meta name="HandheldFriendly" content="True">
|
||||
<meta name="apple-mobile-web-app-title" content="Katbin">
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
|
||||
<meta name="apple-touch-fullscreen" content="yes">
|
||||
|
||||
<%= if assigns[:paste] do %>
|
||||
<meta name="description" content={@paste.content}>
|
||||
<meta itemprop="description" content={@paste.content}>
|
||||
<meta property="og:description" content={@paste.content}>
|
||||
<meta name="twitter:description" content={@paste.content}>
|
||||
|
||||
<meta name="url" content={"https://katb.in/#{@paste.id}"}>
|
||||
<meta name="twitter:url" content={"https://katb.in/#{@paste.id}"}>
|
||||
<meta property="og:url" content={"https://katb.in/#{@paste.id}"}>
|
||||
<% else %>
|
||||
<meta name="description" content="Paste, save, share! A pastebin and URL shortener for all your needs.">
|
||||
<meta property="og:description" content="Paste, save, share! A pastebin and URL shortener for all your needs.">
|
||||
<meta itemprop="og:description" content="Paste, save, share! A pastebin and URL shortener for all your needs.">
|
||||
<meta name="twitter:description" content="Paste, save, share! A pastebin and URL shortener for all your needs.">
|
||||
|
||||
<meta name="url" content="https://katb.in">
|
||||
<meta name="twitter:url" content="https://katb.in">
|
||||
<meta property="og:url" content="https://katb.in">
|
||||
<% end %>
|
||||
|
||||
<link rel="stylesheet" href={ Routes.static_path(@conn, "/assets/app.css") }/>
|
||||
<script defer type="text/javascript" src={ Routes.static_path(@conn, "/assets/app.js") }></script>
|
||||
</head>
|
||||
<body class="flex flex-col ">
|
||||
<header class="flex w-full justify-between items-center py-3 px-6">
|
||||
<a href={ Routes.page_path(@conn, :index) }>
|
||||
<span class="font-semibold text-xl tracking-tight">
|
||||
<span class="text-amber text-xl"><Kat</span>bin/>
|
||||
</span>
|
||||
</a>
|
||||
|
||||
<nav role="navigation">
|
||||
<ul>
|
||||
<%= if function_exported?(Routes, :live_dashboard_path, 2) do %>
|
||||
<li>
|
||||
<%# <%= link "LiveDashboard", to: Routes.live_dashboard_path(@conn, :home) %>
|
||||
</li>
|
||||
<% end %>
|
||||
</ul>
|
||||
<%= render "_user_menu.html", assigns %>
|
||||
</nav>
|
||||
|
||||
</header>
|
||||
<main class="flex flex-col w-full h-full max-h-full overflow-hidden bg-light-grey" role="main">
|
||||
<p class="alert alert-info" role="alert"><%= get_flash(@conn, :info) %></p>
|
||||
<p class="alert alert-danger" role="alert"><%= get_flash(@conn, :error) %></p>
|
||||
<%= @inner_content %>
|
||||
</main>
|
||||
<footer class="font-bold">
|
||||
<div class="flex px-4 py-1 text-xs sm:text-base justify-between text-amber" style="background: #1a1a1a; font-family: JetbrainsMono">
|
||||
<a href="https://sphericalk.at">
|
||||
© <%= DateTime.utc_now().year %> SphericalKat
|
||||
</a>
|
||||
<a href="https://github.com/sphericalkat/katbin">
|
||||
Fork me!
|
||||
</a>
|
||||
</div>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
+1
-1
@@ -1 +1 @@
|
||||
<%= render "form.html", Map.put(assigns, :action, Routes.page_path(@conn, :update, @paste)) %>
|
||||
<%= render "form.html", Map.put(assigns, :action, Routes.page_path(@conn, :update, @paste)) |> Map.put(:is_edit, true) %>
|
||||
+20
-1
@@ -1,13 +1,32 @@
|
||||
<%= form_for @changeset, @action, [class: "flex flex-col w-full h-full relative"], fn f -> %>
|
||||
<%= form_for @changeset, @action, [class: "flex flex-col w-full h-full relative", id: "page_form"], fn f -> %>
|
||||
<script>
|
||||
document.addEventListener("keydown", function(e) {
|
||||
if ((window.navigator.platform.match("Mac") ? e.metaKey : e.ctrlKey) && e.keyCode == 83) {
|
||||
e.preventDefault();
|
||||
document.getElementById("page_form").submit()
|
||||
}
|
||||
}, false);
|
||||
</script>
|
||||
<%= if @changeset.action do %>
|
||||
<div class="w-full text-center bg-amber">
|
||||
<p>Oops, something went wrong!</p>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<%= if assigns[:already_taken] do %>
|
||||
<div class="w-full text-center bg-amber">
|
||||
<p>This custom URL has already been taken.</p>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<div class="w-full h-full">
|
||||
<%= textarea f, :content, [class: "w-full h-full px-6 py-4 outline-none bg-light-grey font-bold resize-none", placeholder: "> Paste, save, share! (Pasting just a URL will shorten it!)"] %>
|
||||
<div class="flex absolute top-0 right-0 p-4">
|
||||
<%= if @current_user && !assigns[:is_edit] do %>
|
||||
<div>
|
||||
<%= text_input f, :custom_url, [class: "px-2 mr-2 outline-none text-black px-2 py-1", placeholder: "Custom URL"] %>
|
||||
</div>
|
||||
<% end %>
|
||||
<button type="submit">
|
||||
<svg
|
||||
class="h-6 w-6 cursor-pointer fill-current text-white hover:text-amber"
|
||||
File renamed without changes.
+6
-2
@@ -1,12 +1,16 @@
|
||||
<div class="flex relative flex-col w-full h-full">
|
||||
<div class="flex absolute top-0 right-0 p-4">
|
||||
<%= if @show_edit do%>
|
||||
<a href="<%= Routes.page_path(@conn, :edit, @paste.id) %>" class="text-white hover:text-amber">
|
||||
<a href={ Routes.page_path(@conn, :edit, @paste.id) } class="text-white hover:text-amber">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="h-6 w-6 cursor-pointer fill-current">
|
||||
<path d="M3 17.46v3.04c0 .28.22.5.5.5h3.04c.13 0 .26-.05.35-.15L17.81 9.94l-3.75-3.75L3.15 17.1c-.1.1-.15.22-.15.36zM20.71 7.04a.996.996 0 0 0 0-1.41l-2.34-2.34a.996.996 0 0 0-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z"></path>
|
||||
</svg>
|
||||
</a>
|
||||
<% end %>
|
||||
</div>
|
||||
<code class="break-word px-6 py-4 h-full w-full nomarkdown overflow-y-auto"><%= raw Ketbin.Utils.Syntax.highlight_text(@paste.content, @extension) |> HtmlSanitizeEx.html5 %></code>
|
||||
<div class="break-word px-6 py-4 h-full w-full overflow-y-auto">
|
||||
<span>
|
||||
Your shortened url is: <a href={Routes.page_path(@conn, :show, @paste.id) }>https://katb.in/<%= @paste.id %></a>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,16 @@
|
||||
<div class="flex relative flex-col w-full h-full">
|
||||
<div class="flex absolute top-0 right-0 p-4">
|
||||
<%= if @show_edit do%>
|
||||
<a href={ Routes.page_path(@conn, :edit, @paste.id) } class="text-white hover:text-amber">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="h-6 w-6 cursor-pointer fill-current">
|
||||
<path d="M3 17.46v3.04c0 .28.22.5.5.5h3.04c.13 0 .26-.05.35-.15L17.81 9.94l-3.75-3.75L3.15 17.1c-.1.1-.15.22-.15.36zM20.71 7.04a.996.996 0 0 0 0-1.41l-2.34-2.34a.996.996 0 0 0-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z"></path>
|
||||
</svg>
|
||||
</a>
|
||||
<% end %>
|
||||
</div>
|
||||
<%= if @extension == "md" do%>
|
||||
<div class="break-word px-6 py-4 h-full w-full markdown overflow-y-auto"><%= raw Earmark.as_html!(@paste.content, escape: true, gfm_tables: true) |> HtmlSanitizeEx.markdown_html %></div>
|
||||
<% else %>
|
||||
<code class="break-word px-6 py-4 h-full w-full overflow-y-auto"><%= raw Ketbin.Utils.Syntax.highlight_text(@paste.content, @extension) |> HtmlSanitizeEx.html5 %></code>
|
||||
<% end %>
|
||||
</div>
|
||||
@@ -1,5 +0,0 @@
|
||||
<h1>Edit Paste</h1>
|
||||
|
||||
<%= render "form.html", Map.put(assigns, :action, Routes.paste_path(@conn, :update, @paste)) %>
|
||||
|
||||
<span><%= link "Back", to: Routes.paste_path(@conn, :index) %></span>
|
||||
@@ -1,19 +0,0 @@
|
||||
<%= form_for @changeset, @action, fn f -> %>
|
||||
<%= if @changeset.action do %>
|
||||
<div class="alert alert-danger">
|
||||
<p>Oops, something went wrong! Please check the errors below.</p>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<%= label f, :is_url %>
|
||||
<%= checkbox f, :is_url %>
|
||||
<%= error_tag f, :is_url %>
|
||||
|
||||
<%= label f, :content %>
|
||||
<%= textarea f, :content %>
|
||||
<%= error_tag f, :content %>
|
||||
|
||||
<div>
|
||||
<%= submit "Save" %>
|
||||
</div>
|
||||
<% end %>
|
||||
@@ -1,28 +0,0 @@
|
||||
<h1>Listing Pastes</h1>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Is url</th>
|
||||
<th>Content</th>
|
||||
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<%= for paste <- @pastes do %>
|
||||
<tr>
|
||||
<td><%= paste.is_url %></td>
|
||||
<td><%= paste.content %></td>
|
||||
|
||||
<td>
|
||||
<span><%= link "Show", to: Routes.paste_path(@conn, :show, paste) %></span>
|
||||
<span><%= link "Edit", to: Routes.paste_path(@conn, :edit, paste) %></span>
|
||||
<span><%= link "Delete", to: Routes.paste_path(@conn, :delete, paste), method: :delete, data: [confirm: "Are you sure?"] %></span>
|
||||
</td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<span><%= link "New Paste", to: Routes.paste_path(@conn, :new) %></span>
|
||||
@@ -1 +0,0 @@
|
||||
<%= render "form.html", Map.put(assigns, :action, Routes.paste_path(@conn, :create)) %>
|
||||
@@ -1,18 +0,0 @@
|
||||
<h1>Show Paste</h1>
|
||||
|
||||
<ul>
|
||||
|
||||
<li>
|
||||
<strong>Is url:</strong>
|
||||
<%= @paste.is_url %>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<strong>Content:</strong>
|
||||
<%= @paste.content %>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
|
||||
<span><%= link "Edit", to: Routes.paste_path(@conn, :edit, @paste) %></span>
|
||||
<span><%= link "Back", to: Routes.paste_path(@conn, :index) %></span>
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
+1
-1
@@ -63,4 +63,4 @@
|
||||
<%= submit "Change password" %>
|
||||
</div>
|
||||
<% end %>
|
||||
<div>
|
||||
</div>
|
||||
@@ -0,0 +1,18 @@
|
||||
defmodule KetbinWeb.Api.PasteView do
|
||||
use KetbinWeb, :view
|
||||
|
||||
def render("paste.json", %{paste: paste}) do
|
||||
%{
|
||||
id: paste.id,
|
||||
content: paste.content,
|
||||
is_url: paste.is_url
|
||||
}
|
||||
end
|
||||
|
||||
def render("error.json", _assigns) do
|
||||
%{
|
||||
success: false,
|
||||
msg: "Something went wrong"
|
||||
}
|
||||
end
|
||||
end
|
||||
@@ -1,3 +0,0 @@
|
||||
defmodule KetbinWeb.PasteView do
|
||||
use KetbinWeb, :view
|
||||
end
|
||||
@@ -5,7 +5,7 @@ defmodule Ketbin.MixProject do
|
||||
[
|
||||
app: :ketbin,
|
||||
version: "0.1.0",
|
||||
elixir: "~> 1.7",
|
||||
elixir: "~> 1.12",
|
||||
elixirc_paths: elixirc_paths(Mix.env()),
|
||||
compilers: [:phoenix, :gettext] ++ Mix.compilers(),
|
||||
start_permanent: Mix.env() == :prod,
|
||||
@@ -20,7 +20,7 @@ defmodule Ketbin.MixProject do
|
||||
def application do
|
||||
[
|
||||
mod: {Ketbin.Application, []},
|
||||
extra_applications: [:logger, :runtime_tools, :ssl],
|
||||
extra_applications: [:logger, :runtime_tools, :ssl]
|
||||
]
|
||||
end
|
||||
|
||||
@@ -34,24 +34,26 @@ defmodule Ketbin.MixProject do
|
||||
defp deps do
|
||||
[
|
||||
{:bcrypt_elixir, "~> 2.0"},
|
||||
{:phoenix, "~> 1.5.10"},
|
||||
{:phoenix_ecto, "~> 4.1"},
|
||||
{:ecto_sql, "~> 3.4"},
|
||||
{:phoenix, "~> 1.6.7"},
|
||||
{:phoenix_ecto, "~> 4.4"},
|
||||
{:ecto_sql, "~> 3.7"},
|
||||
{:postgrex, ">= 0.0.0"},
|
||||
{:phoenix_html, "~> 2.11"},
|
||||
{:phoenix_live_reload, "~> 1.2", only: :dev},
|
||||
{:phoenix_live_dashboard, "~> 0.4"},
|
||||
{:telemetry_metrics, "~> 0.4"},
|
||||
{:telemetry_poller, "~> 0.4"},
|
||||
{:gettext, "~> 0.11"},
|
||||
{:jason, "~> 1.0"},
|
||||
{:plug_cowboy, "~> 2.0"},
|
||||
{:phx_gen_auth, "~> 0.7", only: [:dev], runtime: false},
|
||||
{:rustler, "~> 0.22-rc"},
|
||||
{:phoenix_html, "~> 3.0"},
|
||||
{:phoenix_live_view, "~> 0.18.0"},
|
||||
{:phoenix_live_reload, "~> 1.3", only: :dev},
|
||||
{:phoenix_live_dashboard, "~> 0.8"},
|
||||
{:telemetry_metrics, "~> 0.6"},
|
||||
{:telemetry_poller, "~> 0.5"},
|
||||
{:gettext, "~> 0.18"},
|
||||
{:jason, "~> 1.2"},
|
||||
{:plug_cowboy, "~> 2.5"},
|
||||
{:cors_plug, "~> 3.0"},
|
||||
{:rustler, "~> 0.25"},
|
||||
{:html_sanitize_ex, "~> 1.4"},
|
||||
{:hackney, "~> 1.17"},
|
||||
{:swoosh, "~> 1.5"},
|
||||
{:gen_smtp, "~> 1.1"}
|
||||
{:gen_smtp, "~> 1.1"},
|
||||
{:earmark, "~> 1.4"}
|
||||
]
|
||||
end
|
||||
|
||||
|
||||
@@ -1,49 +1,52 @@
|
||||
%{
|
||||
"bcrypt_elixir": {:hex, :bcrypt_elixir, "2.3.0", "6cb662d5c1b0a8858801cf20997bd006e7016aa8c52959c9ef80e0f34fb60b7a", [:make, :mix], [{:comeonin, "~> 5.3", [hex: :comeonin, repo: "hexpm", optional: false]}, {:elixir_make, "~> 0.6", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm", "2c81d61d4f6ed0e5cf7bf27a9109b791ff216a1034b3d541327484f46dd43769"},
|
||||
"certifi": {:hex, :certifi, "2.6.1", "dbab8e5e155a0763eea978c913ca280a6b544bfa115633fa20249c3d396d9493", [:rebar3], [], "hexpm", "524c97b4991b3849dd5c17a631223896272c6b0af446778ba4675a1dff53bb7e"},
|
||||
"comeonin": {:hex, :comeonin, "5.3.2", "5c2f893d05c56ae3f5e24c1b983c2d5dfb88c6d979c9287a76a7feb1e1d8d646", [:mix], [], "hexpm", "d0993402844c49539aeadb3fe46a3c9bd190f1ecf86b6f9ebd71957534c95f04"},
|
||||
"bcrypt_elixir": {:hex, :bcrypt_elixir, "2.3.1", "5114d780459a04f2b4aeef52307de23de961b69e13a5cd98a911e39fda13f420", [:make, :mix], [{:comeonin, "~> 5.3", [hex: :comeonin, repo: "hexpm", optional: false]}, {:elixir_make, "~> 0.6", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm", "42182d5f46764def15bf9af83739e3bf4ad22661b1c34fc3e88558efced07279"},
|
||||
"castore": {:hex, :castore, "0.1.17", "ba672681de4e51ed8ec1f74ed624d104c0db72742ea1a5e74edbc770c815182f", [:mix], [], "hexpm", "d9844227ed52d26e7519224525cb6868650c272d4a3d327ce3ca5570c12163f9"},
|
||||
"certifi": {:hex, :certifi, "2.9.0", "6f2a475689dd47f19fb74334859d460a2dc4e3252a3324bd2111b8f0429e7e21", [:rebar3], [], "hexpm", "266da46bdb06d6c6d35fde799bcb28d36d985d424ad7c08b5bb48f5b5cdd4641"},
|
||||
"comeonin": {:hex, :comeonin, "5.3.3", "2c564dac95a35650e9b6acfe6d2952083d8a08e4a89b93a481acb552b325892e", [:mix], [], "hexpm", "3e38c9c2cb080828116597ca8807bb482618a315bfafd98c90bc22a821cc84df"},
|
||||
"connection": {:hex, :connection, "1.1.0", "ff2a49c4b75b6fb3e674bfc5536451607270aac754ffd1bdfe175abe4a6d7a68", [:mix], [], "hexpm", "722c1eb0a418fbe91ba7bd59a47e28008a189d47e37e0e7bb85585a016b2869c"},
|
||||
"cors_plug": {:hex, :cors_plug, "3.0.3", "7c3ac52b39624bc616db2e937c282f3f623f25f8d550068b6710e58d04a0e330", [:mix], [{:plug, "~> 1.13", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "3f2d759e8c272ed3835fab2ef11b46bddab8c1ab9528167bd463b6452edf830d"},
|
||||
"cowboy": {:hex, :cowboy, "2.9.0", "865dd8b6607e14cf03282e10e934023a1bd8be6f6bacf921a7e2a96d800cd452", [:make, :rebar3], [{:cowlib, "2.11.0", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "1.8.0", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "2c729f934b4e1aa149aff882f57c6372c15399a20d54f65c8d67bef583021bde"},
|
||||
"cowboy_telemetry": {:hex, :cowboy_telemetry, "0.3.1", "ebd1a1d7aff97f27c66654e78ece187abdc646992714164380d8a041eda16754", [:rebar3], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "3a6efd3366130eab84ca372cbd4a7d3c3a97bdfcfb4911233b035d117063f0af"},
|
||||
"cowlib": {:hex, :cowlib, "2.11.0", "0b9ff9c346629256c42ebe1eeb769a83c6cb771a6ee5960bd110ab0b9b872063", [:make, :rebar3], [], "hexpm", "2b3e9da0b21c4565751a6d4901c20d1b4cc25cbb7fd50d91d2ab6dd287bc86a9"},
|
||||
"db_connection": {:hex, :db_connection, "2.4.0", "d04b1b73795dae60cead94189f1b8a51cc9e1f911c234cc23074017c43c031e5", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "ad416c21ad9f61b3103d254a71b63696ecadb6a917b36f563921e0de00d7d7c8"},
|
||||
"db_connection": {:hex, :db_connection, "2.4.2", "f92e79aff2375299a16bcb069a14ee8615c3414863a6fef93156aee8e86c2ff3", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "4fe53ca91b99f55ea249693a0229356a08f4d1a7931d8ffa79289b145fe83668"},
|
||||
"decimal": {:hex, :decimal, "2.0.0", "a78296e617b0f5dd4c6caf57c714431347912ffb1d0842e998e9792b5642d697", [:mix], [], "hexpm", "34666e9c55dea81013e77d9d87370fe6cb6291d1ef32f46a1600230b1d44f577"},
|
||||
"ecto": {:hex, :ecto, "3.6.2", "efdf52acfc4ce29249bab5417415bd50abd62db7b0603b8bab0d7b996548c2bc", [:mix], [{:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "efad6dfb04e6f986b8a3047822b0f826d9affe8e4ebdd2aeedbfcb14fd48884e"},
|
||||
"ecto_sql": {:hex, :ecto_sql, "3.6.2", "9526b5f691701a5181427634c30655ac33d11e17e4069eff3ae1176c764e0ba3", [:mix], [{:db_connection, "~> 2.2", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.6.2", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.4.0 or ~> 0.5.0", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.15.0 or ~> 1.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:tds, "~> 2.1.1", [hex: :tds, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "5ec9d7e6f742ea39b63aceaea9ac1d1773d574ea40df5a53ef8afbd9242fdb6b"},
|
||||
"elixir_make": {:hex, :elixir_make, "0.6.2", "7dffacd77dec4c37b39af867cedaabb0b59f6a871f89722c25b28fcd4bd70530", [:mix], [], "hexpm", "03e49eadda22526a7e5279d53321d1cced6552f344ba4e03e619063de75348d9"},
|
||||
"earmark": {:hex, :earmark, "1.4.25", "43fd256e37f671528727745f0fc760227e16f40dced303216f766eade06b7b10", [:mix], [{:earmark_parser, "~> 1.4.25", [hex: :earmark_parser, repo: "hexpm", optional: false]}], "hexpm", "073c606ea4c3cc52920e8ae8ebe788c6af03d3e39782b25e5d14ceaa2f692998"},
|
||||
"earmark_parser": {:hex, :earmark_parser, "1.4.25", "2024618731c55ebfcc5439d756852ec4e85978a39d0d58593763924d9a15916f", [:mix], [], "hexpm", "56749c5e1c59447f7b7a23ddb235e4b3defe276afc220a6227237f3efe83f51e"},
|
||||
"ecto": {:hex, :ecto, "3.8.2", "7b9aca632f9da80ffed525354e4de466a66e042abcbc8509b6b600072c8d8ee0", [:mix], [{:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "afe2912cc23f61a6a8466c158331d54e0f427029dd97ca936644bc116d6599b3"},
|
||||
"ecto_sql": {:hex, :ecto_sql, "3.8.1", "1acaaba32ca0551fd19e492fc7c80414e72fc1a7140fc9395aaa53c2e8629798", [:mix], [{:db_connection, "~> 2.5 or ~> 2.4.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.8.1", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.6.0", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.15.0 or ~> 0.16.0 or ~> 1.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:tds, "~> 2.1.1 or ~> 2.2", [hex: :tds, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "ba7fc75882edce6f2ceca047315d5db27ead773cafea47f1724e35f1e7964525"},
|
||||
"elixir_make": {:hex, :elixir_make, "0.6.3", "bc07d53221216838d79e03a8019d0839786703129599e9619f4ab74c8c096eac", [:mix], [], "hexpm", "f5cbd651c5678bcaabdbb7857658ee106b12509cd976c2c2fca99688e1daf716"},
|
||||
"esbuild": {:hex, :esbuild, "0.4.0", "9f17db148aead4cf1e6e6a584214357287a93407b5fb51a031f122b61385d4c2", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}], "hexpm", "b61e4e6b92ffe45e4ee4755a22de6211a67c67987dc02afb35a425a0add1d447"},
|
||||
"file_system": {:hex, :file_system, "0.2.10", "fb082005a9cd1711c05b5248710f8826b02d7d1784e7c3451f9c1231d4fc162d", [:mix], [], "hexpm", "41195edbfb562a593726eda3b3e8b103a309b733ad25f3d642ba49696bf715dc"},
|
||||
"gen_smtp": {:hex, :gen_smtp, "1.1.1", "bf9303c31735100631b1d708d629e4c65944319d1143b5c9952054f4a1311d85", [:rebar3], [{:hut, "1.3.0", [hex: :hut, repo: "hexpm", optional: false]}, {:ranch, ">= 1.7.0", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "51bc50cc017efd4a4248cbc39ea30fb60efa7d4a49688986fafad84434ff9ab7"},
|
||||
"gettext": {:hex, :gettext, "0.18.2", "7df3ea191bb56c0309c00a783334b288d08a879f53a7014341284635850a6e55", [:mix], [], "hexpm", "f9f537b13d4fdd30f3039d33cb80144c3aa1f8d9698e47d7bcbcc8df93b1f5c5"},
|
||||
"hackney": {:hex, :hackney, "1.17.4", "99da4674592504d3fb0cfef0db84c3ba02b4508bae2dff8c0108baa0d6e0977c", [:rebar3], [{:certifi, "~>2.6.1", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "~>6.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "~>1.0.0", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~>1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "3.3.1", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "~>1.1.0", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}, {:unicode_util_compat, "~>0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "de16ff4996556c8548d512f4dbe22dd58a587bf3332e7fd362430a7ef3986b16"},
|
||||
"html_entities": {:hex, :html_entities, "0.5.2", "9e47e70598da7de2a9ff6af8758399251db6dbb7eebe2b013f2bbd2515895c3c", [:mix], [], "hexpm", "c53ba390403485615623b9531e97696f076ed415e8d8058b1dbaa28181f4fdcc"},
|
||||
"html_sanitize_ex": {:hex, :html_sanitize_ex, "1.4.1", "e8a67da405fe9f0d1be121a40a60f70811192033a5b8d00a95dddd807f5e053e", [:mix], [{:mochiweb, "~> 2.15", [hex: :mochiweb, repo: "hexpm", optional: false]}], "hexpm", "68d92656f47cd73598c45ad2394561f025c8c65d146001b955fd7b517858962a"},
|
||||
"hut": {:hex, :hut, "1.3.0", "71f2f054e657c03f959cf1acc43f436ea87580696528ca2a55c8afb1b06c85e7", [:"erlang.mk", :rebar, :rebar3], [], "hexpm", "7e15d28555d8a1f2b5a3a931ec120af0753e4853a4c66053db354f35bf9ab563"},
|
||||
"gen_smtp": {:hex, :gen_smtp, "1.2.0", "9cfc75c72a8821588b9b9fe947ae5ab2aed95a052b81237e0928633a13276fd3", [:rebar3], [{:ranch, ">= 1.8.0", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "5ee0375680bca8f20c4d85f58c2894441443a743355430ff33a783fe03296779"},
|
||||
"gettext": {:hex, :gettext, "0.19.1", "564953fd21f29358e68b91634799d9d26989f8d039d7512622efb3c3b1c97892", [:mix], [], "hexpm", "10c656c0912b8299adba9b061c06947511e3f109ab0d18b44a866a4498e77222"},
|
||||
"hackney": {:hex, :hackney, "1.18.1", "f48bf88f521f2a229fc7bae88cf4f85adc9cd9bcf23b5dc8eb6a1788c662c4f6", [:rebar3], [{:certifi, "~>2.9.0", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "~>6.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "~>1.0.0", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~>1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "3.3.1", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "~>1.1.0", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}, {:unicode_util_compat, "~>0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "a4ecdaff44297e9b5894ae499e9a070ea1888c84afdd1fd9b7b2bc384950128e"},
|
||||
"html_sanitize_ex": {:hex, :html_sanitize_ex, "1.4.2", "c479398b6de798c03eb5d04a0a9a9159d73508f83f6590a00b8eacba3619cf4c", [:mix], [{:mochiweb, "~> 2.15", [hex: :mochiweb, repo: "hexpm", optional: false]}], "hexpm", "aef6c28585d06a9109ad591507e508854c5559561f950bbaea773900dd369b0e"},
|
||||
"idna": {:hex, :idna, "6.1.1", "8a63070e9f7d0c62eb9d9fcb360a7de382448200fbbd1b106cc96d3d8099df8d", [:rebar3], [{:unicode_util_compat, "~>0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "92376eb7894412ed19ac475e4a86f7b413c1b9fbb5bd16dccd57934157944cea"},
|
||||
"jason": {:hex, :jason, "1.2.2", "ba43e3f2709fd1aa1dce90aaabfd039d000469c05c56f0b8e31978e03fa39052", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "18a228f5f0058ee183f29f9eae0805c6e59d61c3b006760668d8d18ff0d12179"},
|
||||
"jason": {:hex, :jason, "1.3.0", "fa6b82a934feb176263ad2df0dbd91bf633d4a46ebfdffea0c8ae82953714946", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "53fc1f51255390e0ec7e50f9cb41e751c260d065dcba2bf0d08dc51a4002c2ac"},
|
||||
"metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"},
|
||||
"mime": {:hex, :mime, "1.6.0", "dabde576a497cef4bbdd60aceee8160e02a6c89250d6c0b29e56c0dfb00db3d2", [:mix], [], "hexpm", "31a1a8613f8321143dde1dafc36006a17d28d02bdfecb9e95a880fa7aabd19a7"},
|
||||
"mime": {:hex, :mime, "2.0.2", "0b9e1a4c840eafb68d820b0e2158ef5c49385d17fb36855ac6e7e087d4b1dcc5", [:mix], [], "hexpm", "e6a3f76b4c277739e36c2e21a2c640778ba4c3846189d5ab19f97f126df5f9b7"},
|
||||
"mimerl": {:hex, :mimerl, "1.2.0", "67e2d3f571088d5cfd3e550c383094b47159f3eee8ffa08e64106cdf5e981be3", [:rebar3], [], "hexpm", "f278585650aa581986264638ebf698f8bb19df297f66ad91b18910dfc6e19323"},
|
||||
"mochiweb": {:hex, :mochiweb, "2.21.0", "3fe5c3403606726d7bc6dabbf36f9d634d5364ce7f33ce73442937fa54feec37", [:rebar3], [], "hexpm", "f848bfa1b75c32d56da9d2730245e34df4b39079c5d45d7b966b072ba53f8a13"},
|
||||
"mochiweb": {:hex, :mochiweb, "2.22.0", "f104d6747c01a330c38613561977e565b788b9170055c5241ac9dd6e4617cba5", [:rebar3], [], "hexpm", "cbbd1fd315d283c576d1c8a13e0738f6dafb63dc840611249608697502a07655"},
|
||||
"parse_trans": {:hex, :parse_trans, "3.3.1", "16328ab840cc09919bd10dab29e431da3af9e9e7e7e6f0089dd5a2d2820011d8", [:rebar3], [], "hexpm", "07cd9577885f56362d414e8c4c4e6bdf10d43a8767abb92d24cbe8b24c54888b"},
|
||||
"phoenix": {:hex, :phoenix, "1.5.10", "3ee7d5c17ff9626d72d374d8fc8909bf00f4323fd15549fbe3abbbd38b5299c8", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_html, "~> 2.13 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 2.0", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:plug, "~> 1.10", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 1.0 or ~> 2.2", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:plug_crypto, "~> 1.1.2 or ~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "f9c2eaa5a8fe5a412610c6aa84ccdb6f3e92f333d4df7fbaeb0d5a157dbfb48d"},
|
||||
"phoenix_ecto": {:hex, :phoenix_ecto, "4.3.0", "2c69a452c2e0ee8c93345ae1cdc1696ef4877ff9cbb15c305def41960c3c4ebf", [:mix], [{:ecto, "~> 3.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.14.2 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "0ac491924217550c8f42c81c1f390b5d81517d12ceaf9abf3e701156760a848e"},
|
||||
"phoenix_html": {:hex, :phoenix_html, "2.14.3", "51f720d0d543e4e157ff06b65de38e13303d5778a7919bcc696599e5934271b8", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "efd697a7fff35a13eeeb6b43db884705cba353a1a41d127d118fda5f90c8e80f"},
|
||||
"phoenix_live_dashboard": {:hex, :phoenix_live_dashboard, "0.4.0", "87990e68b60213d7487e65814046f9a2bed4a67886c943270125913499b3e5c3", [:mix], [{:ecto_psql_extras, "~> 0.4.1 or ~> 0.5", [hex: :ecto_psql_extras, repo: "hexpm", optional: true]}, {:phoenix_html, "~> 2.14.1 or ~> 2.15", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:phoenix_live_view, "~> 0.15.0", [hex: :phoenix_live_view, repo: "hexpm", optional: false]}, {:telemetry_metrics, "~> 0.4.0 or ~> 0.5.0 or ~> 0.6.0", [hex: :telemetry_metrics, repo: "hexpm", optional: false]}], "hexpm", "8d52149e58188e9e4497cc0d8900ab94d9b66f96998ec38c47c7a4f8f4f50e57"},
|
||||
"phoenix": {:hex, :phoenix, "1.6.7", "f1de32418bbbcd471f4fe74d3860ee9c8e8c6c36a0ec173be8ff468a5d72ac90", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 2.0", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 1.0", [hex: :phoenix_view, repo: "hexpm", optional: false]}, {:plug, "~> 1.10", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.2", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:plug_crypto, "~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "b354a4f11d9a2f3a380fb731042dae064f22d7aed8c7e7c024a2459f12994aad"},
|
||||
"phoenix_ecto": {:hex, :phoenix_ecto, "4.4.0", "0672ed4e4808b3fbed494dded89958e22fb882de47a97634c0b13e7b0b5f7720", [:mix], [{:ecto, "~> 3.3", [hex: :ecto, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.14.2 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:plug, "~> 1.9", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "09864e558ed31ee00bd48fcc1d4fc58ae9678c9e81649075431e69dbabb43cc1"},
|
||||
"phoenix_html": {:hex, :phoenix_html, "3.2.0", "1c1219d4b6cb22ac72f12f73dc5fad6c7563104d083f711c3fcd8551a1f4ae11", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "36ec97ba56d25c0136ef1992c37957e4246b649d620958a1f9fa86165f8bc54f"},
|
||||
"phoenix_live_dashboard": {:hex, :phoenix_live_dashboard, "0.5.3", "ff153c46aee237dd7244f07e9b98d557fe0d1de7a5916438e634c3be2d13c607", [:mix], [{:ecto, "~> 3.6.2 or ~> 3.7", [hex: :ecto, repo: "hexpm", optional: true]}, {:ecto_psql_extras, "~> 0.7", [hex: :ecto_psql_extras, repo: "hexpm", optional: true]}, {:phoenix_live_view, "~> 0.16.0", [hex: :phoenix_live_view, repo: "hexpm", optional: false]}, {:telemetry_metrics, "~> 0.6.0", [hex: :telemetry_metrics, repo: "hexpm", optional: false]}], "hexpm", "e36e62b1f61c19b645853af78290a5e7900f7cae1e676714ff69f9836e2f2e76"},
|
||||
"phoenix_live_reload": {:hex, :phoenix_live_reload, "1.3.3", "3a53772a6118d5679bf50fc1670505a290e32a1d195df9e069d8c53ab040c054", [:mix], [{:file_system, "~> 0.2.1 or ~> 0.3", [hex: :file_system, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.4", [hex: :phoenix, repo: "hexpm", optional: false]}], "hexpm", "766796676e5f558dbae5d1bdb066849673e956005e3730dfd5affd7a6da4abac"},
|
||||
"phoenix_live_view": {:hex, :phoenix_live_view, "0.15.7", "09720b8e5151b3ca8ef739cd7626d4feb987c69ba0b509c9bbdb861d5a365881", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix, "~> 1.5.7", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.14", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.2 or ~> 0.5", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "3a756cf662420272d0f1b3b908cce5222163b5a95aa9bab404f9d29aff53276e"},
|
||||
"phoenix_pubsub": {:hex, :phoenix_pubsub, "2.0.0", "a1ae76717bb168cdeb10ec9d92d1480fec99e3080f011402c0a2d68d47395ffb", [:mix], [], "hexpm", "c52d948c4f261577b9c6fa804be91884b381a7f8f18450c5045975435350f771"},
|
||||
"phx_gen_auth": {:hex, :phx_gen_auth, "0.7.0", "2e10e9527b6b71abbfbb4601c7dc4aa4fb9f2db6f9a6be457c468b7f2b0f6319", [:mix], [{:phoenix, "~> 1.5.2", [hex: :phoenix, repo: "hexpm", optional: false]}], "hexpm", "b9dc3e3b866e67c5db8f00f4a2adb28fc8636e794f78600e35aba0e55bdac209"},
|
||||
"plug": {:hex, :plug, "1.12.1", "645678c800601d8d9f27ad1aebba1fdb9ce5b2623ddb961a074da0b96c35187d", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "d57e799a777bc20494b784966dc5fbda91eb4a09f571f76545b72a634ce0d30b"},
|
||||
"plug_cowboy": {:hex, :plug_cowboy, "2.5.1", "7cc96ff645158a94cf3ec9744464414f02287f832d6847079adfe0b58761cbd0", [:mix], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:cowboy_telemetry, "~> 0.3", [hex: :cowboy_telemetry, repo: "hexpm", optional: false]}, {:plug, "~> 1.7", [hex: :plug, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "107d0a5865fa92bcb48e631cc0729ae9ccfa0a9f9a1bd8f01acb513abf1c2d64"},
|
||||
"phoenix_live_view": {:hex, :phoenix_live_view, "0.16.4", "5692edd0bac247a9a816eee7394e32e7a764959c7d0cf9190662fc8b0cd24c97", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix, "~> 1.5.9 or ~> 1.6.0", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "754ba49aa2e8601afd4f151492c93eb72df69b0b9856bab17711b8397e43bba0"},
|
||||
"phoenix_pubsub": {:hex, :phoenix_pubsub, "2.1.1", "ba04e489ef03763bf28a17eb2eaddc2c20c6d217e2150a61e3298b0f4c2012b5", [:mix], [], "hexpm", "81367c6d1eea5878ad726be80808eb5a787a23dee699f96e72b1109c57cdd8d9"},
|
||||
"phoenix_view": {:hex, :phoenix_view, "1.1.2", "1b82764a065fb41051637872c7bd07ed2fdb6f5c3bd89684d4dca6e10115c95a", [:mix], [{:phoenix_html, "~> 2.14.2 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}], "hexpm", "7ae90ad27b09091266f6adbb61e1d2516a7c3d7062c6789d46a7554ec40f3a56"},
|
||||
"plug": {:hex, :plug, "1.13.6", "187beb6b67c6cec50503e940f0434ea4692b19384d47e5fdfd701e93cadb4cc2", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "02b9c6b9955bce92c829f31d6284bf53c591ca63c4fb9ff81dfd0418667a34ff"},
|
||||
"plug_cowboy": {:hex, :plug_cowboy, "2.5.2", "62894ccd601cf9597e2c23911ff12798a8a18d237e9739f58a6b04e4988899fe", [:mix], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:cowboy_telemetry, "~> 0.3", [hex: :cowboy_telemetry, repo: "hexpm", optional: false]}, {:plug, "~> 1.7", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "ea6e87f774c8608d60c8d34022a7d073bd7680a0a013f049fc62bf35efea1044"},
|
||||
"plug_crypto": {:hex, :plug_crypto, "1.2.2", "05654514ac717ff3a1843204b424477d9e60c143406aa94daf2274fdd280794d", [:mix], [], "hexpm", "87631c7ad914a5a445f0a3809f99b079113ae4ed4b867348dd9eec288cecb6db"},
|
||||
"postgrex": {:hex, :postgrex, "0.15.10", "2809dee1b1d76f7cbabe570b2a9285c2e7b41be60cf792f5f2804a54b838a067", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm", "1560ca427542f6b213f8e281633ae1a3b31cdbcd84ebd7f50628765b8f6132be"},
|
||||
"postgrex": {:hex, :postgrex, "0.16.3", "fac79a81a9a234b11c44235a4494d8565303fa4b9147acf57e48978a074971db", [:mix], [{:connection, "~> 1.1", [hex: :connection, repo: "hexpm", optional: false]}, {:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "aeaae1d2d1322da4e5fe90d241b0a564ce03a3add09d7270fb85362166194590"},
|
||||
"ranch": {:hex, :ranch, "1.8.0", "8c7a100a139fd57f17327b6413e4167ac559fbc04ca7448e9be9057311597a1d", [:make, :rebar3], [], "hexpm", "49fbcfd3682fab1f5d109351b61257676da1a2fdbe295904176d5e521a2ddfe5"},
|
||||
"rustler": {:hex, :rustler, "0.22.0", "e2930f9d6933e910f87526bb0a7f904e32b62a7e838a3ca4a884ee7fdfb957ed", [:mix], [{:toml, "~> 0.5.2", [hex: :toml, repo: "hexpm", optional: false]}], "hexpm", "01f5989dd511ebec09be481e07d3c59773d5373c5061e09d3ebc3ef61811b49d"},
|
||||
"rustler": {:hex, :rustler, "0.25.0", "32526b51af7e58a740f61941bf923486ce6415a91c3934cc16c281aa201a2240", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:toml, "~> 0.6", [hex: :toml, repo: "hexpm", optional: false]}], "hexpm", "6b43a11a37fe79c6234d88c4102ab5dfede7a6a764dc5c7b539956cfa02f3cf4"},
|
||||
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.6", "cf344f5692c82d2cd7554f5ec8fd961548d4fd09e7d22f5b62482e5aeaebd4b0", [:make, :mix, :rebar3], [], "hexpm", "bdb0d2471f453c88ff3908e7686f86f9be327d065cc1ec16fa4540197ea04680"},
|
||||
"swoosh": {:hex, :swoosh, "1.5.0", "2be4cfc1be10f2203d1854c85b18d8c7be0321445a782efd53ef0b2b88f03ce4", [:mix], [{:cowboy, "~> 1.1 or ~> 2.4", [hex: :cowboy, repo: "hexpm", optional: true]}, {:finch, "~> 0.6", [hex: :finch, repo: "hexpm", optional: true]}, {:gen_smtp, "~> 0.13 or ~> 1.0", [hex: :gen_smtp, repo: "hexpm", optional: true]}, {:hackney, "~> 1.9", [hex: :hackney, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mail, "~> 0.2", [hex: :mail, repo: "hexpm", optional: true]}, {:mime, "~> 1.1 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_cowboy, ">= 1.0.0", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "b53891359e3ddca263ece784051243de84c9244c421a0dee1bff1d52fc5ca420"},
|
||||
"swoosh": {:hex, :swoosh, "1.6.6", "6018c6f4659ac0b4f30684982993b7812b2bb97436d39f76fcfa8c9e3ae74f85", [:mix], [{:cowboy, "~> 1.1 or ~> 2.4", [hex: :cowboy, repo: "hexpm", optional: true]}, {:ex_aws, "~> 2.1", [hex: :ex_aws, repo: "hexpm", optional: true]}, {:finch, "~> 0.6", [hex: :finch, repo: "hexpm", optional: true]}, {:gen_smtp, "~> 0.13 or ~> 1.0", [hex: :gen_smtp, repo: "hexpm", optional: true]}, {:hackney, "~> 1.9", [hex: :hackney, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mail, "~> 0.2", [hex: :mail, repo: "hexpm", optional: true]}, {:mime, "~> 1.1 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_cowboy, ">= 1.0.0", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "e92c7206efd442f08484993676ab072afab2f2bb1e87e604230bb1183c5980de"},
|
||||
"telemetry": {:hex, :telemetry, "0.4.3", "a06428a514bdbc63293cd9a6263aad00ddeb66f608163bdec7c8995784080818", [:rebar3], [], "hexpm", "eb72b8365ffda5bed68a620d1da88525e326cb82a75ee61354fc24b844768041"},
|
||||
"telemetry_metrics": {:hex, :telemetry_metrics, "0.6.1", "315d9163a1d4660aedc3fee73f33f1d355dcc76c5c3ab3d59e76e3edf80eef1f", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "7be9e0871c41732c233be71e4be11b96e56177bf15dde64a8ac9ce72ac9834c6"},
|
||||
"telemetry_poller": {:hex, :telemetry_poller, "0.5.1", "21071cc2e536810bac5628b935521ff3e28f0303e770951158c73eaaa01e962a", [:rebar3], [{:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "4cab72069210bc6e7a080cec9afffad1b33370149ed5d379b81c7c5f0c663fd4"},
|
||||
"toml": {:hex, :toml, "0.5.2", "e471388a8726d1ce51a6b32f864b8228a1eb8edc907a0edf2bb50eab9321b526", [:mix], [], "hexpm", "f1e3dabef71fb510d015fad18c0e05e7c57281001141504c6b69d94e99750a07"},
|
||||
"toml": {:hex, :toml, "0.6.2", "38f445df384a17e5d382befe30e3489112a48d3ba4c459e543f748c2f25dd4d1", [:mix], [], "hexpm", "d013e45126d74c0c26a38d31f5e8e9b83ea19fc752470feb9a86071ca5a672fa"},
|
||||
"unicode_util_compat": {:hex, :unicode_util_compat, "0.7.0", "bc84380c9ab48177092f43ac89e4dfa2c6d62b40b8bd132b1059ecc7232f9a78", [:rebar3], [], "hexpm", "25eee6d67df61960cf6a794239566599b09e17e668d3700247bc498638152521"},
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
[target.x86_64-apple-darwin]
|
||||
[target.'cfg(target_os = "macos")']
|
||||
rustflags = [
|
||||
"-C", "link-arg=-undefined",
|
||||
"-C", "link-arg=dynamic_lookup",
|
||||
|
||||
@@ -4,16 +4,16 @@ defmodule Ketbin.Repo.Migrations.CreateUsersAuthTables do
|
||||
def change do
|
||||
execute "CREATE EXTENSION IF NOT EXISTS citext", ""
|
||||
|
||||
create table(:users) do
|
||||
create_if_not_exists table(:users) do
|
||||
add :email, :citext, null: false
|
||||
add :hashed_password, :string, null: false
|
||||
add :confirmed_at, :naive_datetime
|
||||
timestamps()
|
||||
end
|
||||
|
||||
create unique_index(:users, [:email])
|
||||
create_if_not_exists unique_index(:users, [:email])
|
||||
|
||||
create table(:users_tokens) do
|
||||
create_if_not_exists table(:users_tokens) do
|
||||
add :user_id, references(:users, on_delete: :delete_all), null: false
|
||||
add :token, :binary, null: false
|
||||
add :context, :string, null: false
|
||||
@@ -21,7 +21,7 @@ defmodule Ketbin.Repo.Migrations.CreateUsersAuthTables do
|
||||
timestamps(updated_at: false)
|
||||
end
|
||||
|
||||
create index(:users_tokens, [:user_id])
|
||||
create unique_index(:users_tokens, [:context, :token])
|
||||
create_if_not_exists index(:users_tokens, [:user_id])
|
||||
create_if_not_exists unique_index(:users_tokens, [:context, :token])
|
||||
end
|
||||
end
|
||||
@@ -2,13 +2,13 @@ defmodule Ketbin.Repo.Migrations.CreatePastes do
|
||||
use Ecto.Migration
|
||||
|
||||
def change do
|
||||
create table(:pastes, primary_key: false) do
|
||||
create_if_not_exists table(:pastes, primary_key: false) do
|
||||
add :id, :string, primary_key: true
|
||||
add :is_url, :boolean, default: false, null: false
|
||||
add :content, :text, null: false
|
||||
add :belongs_to, references(:users, on_delete: :delete_all)
|
||||
end
|
||||
|
||||
create index(:pastes, [:belongs_to])
|
||||
create_if_not_exists index(:pastes, [:belongs_to])
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,220 @@
|
||||
--
|
||||
-- PostgreSQL database dump
|
||||
--
|
||||
|
||||
-- Dumped from database version 13.4 (Debian 13.4-1.pgdg100+1)
|
||||
-- Dumped by pg_dump version 13.4
|
||||
|
||||
SET statement_timeout = 0;
|
||||
SET lock_timeout = 0;
|
||||
SET idle_in_transaction_session_timeout = 0;
|
||||
SET client_encoding = 'UTF8';
|
||||
SET standard_conforming_strings = on;
|
||||
SELECT pg_catalog.set_config('search_path', '', false);
|
||||
SET check_function_bodies = false;
|
||||
SET xmloption = content;
|
||||
SET client_min_messages = warning;
|
||||
SET row_security = off;
|
||||
|
||||
--
|
||||
-- Name: citext; Type: EXTENSION; Schema: -; Owner: -
|
||||
--
|
||||
|
||||
CREATE EXTENSION IF NOT EXISTS citext WITH SCHEMA public;
|
||||
|
||||
|
||||
--
|
||||
-- Name: EXTENSION citext; Type: COMMENT; Schema: -; Owner: -
|
||||
--
|
||||
|
||||
COMMENT ON EXTENSION citext IS 'data type for case-insensitive character strings';
|
||||
|
||||
|
||||
SET default_tablespace = '';
|
||||
|
||||
SET default_table_access_method = heap;
|
||||
|
||||
--
|
||||
-- Name: pastes; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.pastes (
|
||||
id character varying(255) NOT NULL,
|
||||
is_url boolean DEFAULT false NOT NULL,
|
||||
content text NOT NULL,
|
||||
belongs_to bigint
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: schema_migrations; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.schema_migrations (
|
||||
version bigint NOT NULL,
|
||||
inserted_at timestamp(0) without time zone
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: users; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.users (
|
||||
id bigint NOT NULL,
|
||||
email public.citext NOT NULL,
|
||||
hashed_password character varying(255) NOT NULL,
|
||||
confirmed_at timestamp(0) without time zone,
|
||||
inserted_at timestamp(0) without time zone NOT NULL,
|
||||
updated_at timestamp(0) without time zone NOT NULL
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: users_id_seq; Type: SEQUENCE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE SEQUENCE public.users_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
|
||||
--
|
||||
-- Name: users_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER SEQUENCE public.users_id_seq OWNED BY public.users.id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: users_tokens; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.users_tokens (
|
||||
id bigint NOT NULL,
|
||||
user_id bigint NOT NULL,
|
||||
token bytea NOT NULL,
|
||||
context character varying(255) NOT NULL,
|
||||
sent_to character varying(255),
|
||||
inserted_at timestamp(0) without time zone NOT NULL
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: users_tokens_id_seq; Type: SEQUENCE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE SEQUENCE public.users_tokens_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
|
||||
--
|
||||
-- Name: users_tokens_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER SEQUENCE public.users_tokens_id_seq OWNED BY public.users_tokens.id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: users id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.users ALTER COLUMN id SET DEFAULT nextval('public.users_id_seq'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: users_tokens id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.users_tokens ALTER COLUMN id SET DEFAULT nextval('public.users_tokens_id_seq'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: pastes pastes_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.pastes
|
||||
ADD CONSTRAINT pastes_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: schema_migrations schema_migrations_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.schema_migrations
|
||||
ADD CONSTRAINT schema_migrations_pkey PRIMARY KEY (version);
|
||||
|
||||
|
||||
--
|
||||
-- Name: users users_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.users
|
||||
ADD CONSTRAINT users_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: users_tokens users_tokens_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.users_tokens
|
||||
ADD CONSTRAINT users_tokens_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: pastes_belongs_to_index; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX pastes_belongs_to_index ON public.pastes USING btree (belongs_to);
|
||||
|
||||
|
||||
--
|
||||
-- Name: users_email_index; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE UNIQUE INDEX users_email_index ON public.users USING btree (email);
|
||||
|
||||
|
||||
--
|
||||
-- Name: users_tokens_context_token_index; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE UNIQUE INDEX users_tokens_context_token_index ON public.users_tokens USING btree (context, token);
|
||||
|
||||
|
||||
--
|
||||
-- Name: users_tokens_user_id_index; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX users_tokens_user_id_index ON public.users_tokens USING btree (user_id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: pastes pastes_belongs_to_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.pastes
|
||||
ADD CONSTRAINT pastes_belongs_to_fkey FOREIGN KEY (belongs_to) REFERENCES public.users(id) ON DELETE CASCADE;
|
||||
|
||||
|
||||
--
|
||||
-- Name: users_tokens users_tokens_user_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.users_tokens
|
||||
ADD CONSTRAINT users_tokens_user_id_fkey FOREIGN KEY (user_id) REFERENCES public.users(id) ON DELETE CASCADE;
|
||||
|
||||
|
||||
--
|
||||
-- PostgreSQL database dump complete
|
||||
--
|
||||
|
||||
INSERT INTO public."schema_migrations" (version) VALUES (20210811065554);
|
||||
INSERT INTO public."schema_migrations" (version) VALUES (20210811213141);
|
||||
Executable
+3
@@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
cd -P -- "$(dirname -- "$0")"
|
||||
PHX_SERVER=true exec ./ketbin start
|
||||
Executable
+2
@@ -0,0 +1,2 @@
|
||||
set PHX_SERVER=true
|
||||
call "%~dp0\ketbin" start
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
||||
"extends": [
|
||||
"config:base"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
DATABASE_URL='<insert db url here>'
|
||||
SECRET_KEY_BASE='<insert secret key here>'
|
||||
SWOOSH_USERNAME='noreply@katb.in'
|
||||
SWOOSH_PASSWORD='<insert your password here>'
|
||||
SWOOSH_SMTP_RELAY='smtp.example.com'
|
||||
@@ -75,6 +75,7 @@ defmodule KetbinWeb.PasteControllerTest do
|
||||
test "deletes chosen paste", %{conn: conn, paste: paste} do
|
||||
conn = delete(conn, Routes.paste_path(conn, :delete, paste))
|
||||
assert redirected_to(conn) == Routes.paste_path(conn, :index)
|
||||
|
||||
assert_error_sent 404, fn ->
|
||||
get(conn, Routes.paste_path(conn, :show, paste))
|
||||
end
|
||||
|
||||
Reference in new issue
Block a user