Merge branch 'develop' into oembed_provider
This commit is contained in:
commit
7fb3780431
|
@ -13,6 +13,7 @@ cache:
|
|||
key: ${CI_COMMIT_REF_SLUG}
|
||||
paths:
|
||||
- deps
|
||||
- _build
|
||||
stages:
|
||||
- lint
|
||||
- test
|
||||
|
@ -21,6 +22,7 @@ before_script:
|
|||
- mix local.hex --force
|
||||
- mix local.rebar --force
|
||||
- mix deps.get
|
||||
- mix compile --force
|
||||
- MIX_ENV=test mix ecto.create
|
||||
- MIX_ENV=test mix ecto.migrate
|
||||
|
||||
|
|
6
.idea/libraries/gen_smtp.xml
Normal file
6
.idea/libraries/gen_smtp.xml
Normal file
|
@ -0,0 +1,6 @@
|
|||
<component name="libraryTable">
|
||||
<library name="gen_smtp" type="mix">
|
||||
<CLASSES />
|
||||
<SOURCES />
|
||||
</library>
|
||||
</component>
|
6
.idea/libraries/html_entities.xml
Normal file
6
.idea/libraries/html_entities.xml
Normal file
|
@ -0,0 +1,6 @@
|
|||
<component name="libraryTable">
|
||||
<library name="html_entities" type="mix">
|
||||
<CLASSES />
|
||||
<SOURCES />
|
||||
</library>
|
||||
</component>
|
8
.idea/libraries/plug_cowboy.xml
Normal file
8
.idea/libraries/plug_cowboy.xml
Normal file
|
@ -0,0 +1,8 @@
|
|||
<component name="libraryTable">
|
||||
<library name="plug_cowboy" type="mix">
|
||||
<CLASSES />
|
||||
<SOURCES>
|
||||
<root url="file://$PROJECT_DIR$/deps/plug_cowboy/lib" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
</component>
|
8
.idea/libraries/plug_crypto.xml
Normal file
8
.idea/libraries/plug_crypto.xml
Normal file
|
@ -0,0 +1,8 @@
|
|||
<component name="libraryTable">
|
||||
<library name="plug_crypto" type="mix">
|
||||
<CLASSES />
|
||||
<SOURCES>
|
||||
<root url="file://$PROJECT_DIR$/deps/plug_crypto/lib" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
</component>
|
6
.idea/libraries/swoosh.xml
Normal file
6
.idea/libraries/swoosh.xml
Normal file
|
@ -0,0 +1,6 @@
|
|||
<component name="libraryTable">
|
||||
<library name="swoosh" type="mix">
|
||||
<CLASSES />
|
||||
<SOURCES />
|
||||
</library>
|
||||
</component>
|
|
@ -137,8 +137,8 @@
|
|||
logo_mask: true,
|
||||
logo_margin: "0.1em",
|
||||
background: "/static/aurora_borealis.jpg",
|
||||
redirect_root_no_login: "/main/all",
|
||||
redirect_root_login: "/main/friends",
|
||||
redirect_root_no_login: "/~/main/all",
|
||||
redirect_root_login: "/~/main/friends",
|
||||
show_instance_panel: true,
|
||||
scope_options_enabled: false,
|
||||
formatting_options_enabled: false,
|
||||
|
|
|
@ -175,3 +175,16 @@ the source code is here: https://github.com/koto-bank/kocaptcha. The default end
|
|||
`https://captcha.kotobank.ch` is hosted by the developer.
|
||||
|
||||
* `endpoint`: the kocaptcha endpoint to use
|
||||
|
||||
## :admin_token
|
||||
|
||||
Allows to set a token that can be used to authenticate with the admin api without using an actual user by giving it as the 'admin_token' parameter. Example:
|
||||
|
||||
```
|
||||
config :pleroma, :admin_token, "somerandomtoken"
|
||||
```
|
||||
|
||||
You can then do
|
||||
```
|
||||
curl "http://localhost:4000/api/pleroma/admin/invite_token?admin_token=somerandomtoken"
|
||||
```
|
||||
|
|
|
@ -4,12 +4,12 @@ defmodule Pleroma.Formatter do
|
|||
alias Pleroma.HTML
|
||||
alias Pleroma.Emoji
|
||||
|
||||
@tag_regex ~r/\#\w+/u
|
||||
@tag_regex ~r/((?<=[^&])|\A)(\#)(\w+)/u
|
||||
@markdown_characters_regex ~r/(`|\*|_|{|}|[|]|\(|\)|#|\+|-|\.|!)/
|
||||
|
||||
def parse_tags(text, data \\ %{}) do
|
||||
Regex.scan(@tag_regex, text)
|
||||
|> Enum.map(fn ["#" <> tag = full_tag] -> {full_tag, String.downcase(tag)} end)
|
||||
|> Enum.map(fn ["#" <> tag = full_tag | _] -> {full_tag, String.downcase(tag)} end)
|
||||
|> (fn map ->
|
||||
if data["sensitive"] in [true, "True", "true", "1"],
|
||||
do: [{"#nsfw", "nsfw"}] ++ map,
|
||||
|
@ -155,7 +155,7 @@ def add_hashtag_links({subs, text}, tags) do
|
|||
uuid_text =
|
||||
tags
|
||||
|> Enum.reduce(text, fn {match, _short, uuid}, text ->
|
||||
String.replace(text, match, uuid)
|
||||
String.replace(text, ~r/((?<=[^&])|(\A))#{match}/, uuid)
|
||||
end)
|
||||
|
||||
subs =
|
||||
|
|
25
lib/pleroma/plugs/admin_secret_authentication_plug.ex
Normal file
25
lib/pleroma/plugs/admin_secret_authentication_plug.ex
Normal file
|
@ -0,0 +1,25 @@
|
|||
defmodule Pleroma.Plugs.AdminSecretAuthenticationPlug do
|
||||
import Plug.Conn
|
||||
alias Pleroma.User
|
||||
|
||||
def init(options) do
|
||||
options
|
||||
end
|
||||
|
||||
def secret_token do
|
||||
Pleroma.Config.get(:admin_token)
|
||||
end
|
||||
|
||||
def call(%{assigns: %{user: %User{}}} = conn, _), do: conn
|
||||
|
||||
def call(%{params: %{"admin_token" => admin_token}} = conn, _) do
|
||||
if secret_token() && admin_token == secret_token() do
|
||||
conn
|
||||
|> assign(:user, %User{info: %{is_admin: true}})
|
||||
else
|
||||
conn
|
||||
end
|
||||
end
|
||||
|
||||
def call(conn, _), do: conn
|
||||
end
|
|
@ -38,6 +38,7 @@ defmodule Pleroma.Web.Router do
|
|||
plug(Pleroma.Plugs.SessionAuthenticationPlug)
|
||||
plug(Pleroma.Plugs.LegacyAuthenticationPlug)
|
||||
plug(Pleroma.Plugs.AuthenticationPlug)
|
||||
plug(Pleroma.Plugs.AdminSecretAuthenticationPlug)
|
||||
plug(Pleroma.Plugs.UserEnabledPlug)
|
||||
plug(Pleroma.Plugs.SetUserSessionIdPlug)
|
||||
plug(Pleroma.Plugs.EnsureAuthenticatedPlug)
|
||||
|
|
|
@ -1 +1 @@
|
|||
<!DOCTYPE html><html lang=en><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1"><title>Pleroma</title><!--server-generated-meta--><link rel=icon type=image/png href=/favicon.png><link rel=stylesheet href=/static/font/css/fontello.css><link rel=stylesheet href=/static/font/css/animation.css><link href=/static/css/app.ea00efb3229c8591fcc5249f0241b986.css rel=stylesheet></head><body style="display: none"><div id=app></div><script type=text/javascript src=/static/js/manifest.e076977b8e6c6844fb00.js></script><script type=text/javascript src=/static/js/vendor.cc4190750f6ed4d697bd.js></script><script type=text/javascript src=/static/js/app.67f548ecb9e9fd6b25b0.js></script></body></html>
|
||||
<!DOCTYPE html><html lang=en><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1"><title>Pleroma</title><!--server-generated-meta--><link rel=icon type=image/png href=/favicon.png><link rel=stylesheet href=/static/font/css/fontello.css><link rel=stylesheet href=/static/font/css/animation.css><link href=/static/css/app.285fa56c62b811bbd37880f7e2656b13.css rel=stylesheet></head><body style="display: none"><div id=app></div><script type=text/javascript src=/static/js/manifest.60e190da7cc4cc4711dc.js></script><script type=text/javascript src=/static/js/vendor.48d4753220bd83360796.js></script><script type=text/javascript src=/static/js/app.6cb7378f44092df9536a.js></script></body></html>
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
"logo": "/static/logo.png",
|
||||
"logoMask": true,
|
||||
"logoMargin": ".1em",
|
||||
"redirectRootNoLogin": "/main/all",
|
||||
"redirectRootLogin": "/main/friends",
|
||||
"redirectRootNoLogin": "/~/main/all",
|
||||
"redirectRootLogin": "/~/main/friends",
|
||||
"chatDisabled": false,
|
||||
"showInstanceSpecificPanel": false,
|
||||
"scopeOptionsEnabled": false,
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
13
priv/static/static/js/app.6cb7378f44092df9536a.js
Normal file
13
priv/static/static/js/app.6cb7378f44092df9536a.js
Normal file
File diff suppressed because one or more lines are too long
1
priv/static/static/js/app.6cb7378f44092df9536a.js.map
Normal file
1
priv/static/static/js/app.6cb7378f44092df9536a.js.map
Normal file
File diff suppressed because one or more lines are too long
|
@ -1,2 +1,2 @@
|
|||
!function(e){function t(r){if(n[r])return n[r].exports;var a=n[r]={exports:{},id:r,loaded:!1};return e[r].call(a.exports,a,a.exports,t),a.loaded=!0,a.exports}var r=window.webpackJsonp;window.webpackJsonp=function(o,p){for(var c,l,s=0,i=[];s<o.length;s++)l=o[s],a[l]&&i.push.apply(i,a[l]),a[l]=0;for(c in p)Object.prototype.hasOwnProperty.call(p,c)&&(e[c]=p[c]);for(r&&r(o,p);i.length;)i.shift().call(null,t);if(p[0])return n[0]=0,t(0)};var n={},a={0:0};t.e=function(e,r){if(0===a[e])return r.call(null,t);if(void 0!==a[e])a[e].push(r);else{a[e]=[r];var n=document.getElementsByTagName("head")[0],o=document.createElement("script");o.type="text/javascript",o.charset="utf-8",o.async=!0,o.src=t.p+"static/js/"+e+"."+{1:"b578d16088622c18d886",2:"0220742f52d6912415d5"}[e]+".js",n.appendChild(o)}},t.m=e,t.c=n,t.p="/"}([]);
|
||||
//# sourceMappingURL=manifest.f0b8300215e3fdbb725f.js.map
|
||||
!function(e){function t(r){if(n[r])return n[r].exports;var a=n[r]={exports:{},id:r,loaded:!1};return e[r].call(a.exports,a,a.exports,t),a.loaded=!0,a.exports}var r=window.webpackJsonp;window.webpackJsonp=function(o,p){for(var c,l,s=0,i=[];s<o.length;s++)l=o[s],a[l]&&i.push.apply(i,a[l]),a[l]=0;for(c in p)Object.prototype.hasOwnProperty.call(p,c)&&(e[c]=p[c]);for(r&&r(o,p);i.length;)i.shift().call(null,t);if(p[0])return n[0]=0,t(0)};var n={},a={0:0};t.e=function(e,r){if(0===a[e])return r.call(null,t);if(void 0!==a[e])a[e].push(r);else{a[e]=[r];var n=document.getElementsByTagName("head")[0],o=document.createElement("script");o.type="text/javascript",o.charset="utf-8",o.async=!0,o.src=t.p+"static/js/"+e+"."+{1:"48d4753220bd83360796",2:"6cb7378f44092df9536a"}[e]+".js",n.appendChild(o)}},t.m=e,t.c=n,t.p="/"}([]);
|
||||
//# sourceMappingURL=manifest.60e190da7cc4cc4711dc.js.map
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
priv/static/static/js/vendor.48d4753220bd83360796.js.map
Normal file
1
priv/static/static/js/vendor.48d4753220bd83360796.js.map
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1,4 +1,4 @@
|
|||
var serviceWorkerOption = {"assets":["/static/img/nsfw.50fd83c.png","/static/js/manifest.f0b8300215e3fdbb725f.js","/static/js/vendor.b578d16088622c18d886.js","/static/js/app.0220742f52d6912415d5.js","/static/css/app.a37e07355ec1b0b45e84807615297c27.css"]};
|
||||
var serviceWorkerOption = {"assets":["/static/img/nsfw.50fd83c.png","/static/js/manifest.60e190da7cc4cc4711dc.js","/static/js/vendor.48d4753220bd83360796.js","/static/js/app.6cb7378f44092df9536a.js","/static/css/app.285fa56c62b811bbd37880f7e2656b13.css"]};
|
||||
|
||||
!function(e){function t(r){if(n[r])return n[r].exports;var o=n[r]={exports:{},id:r,loaded:!1};return e[r].call(o.exports,o,o.exports,t),o.loaded=!0,o.exports}var n={};return t.m=e,t.c=n,t.p="/",t(0)}([function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function o(){return u.default.getItem("vuex-lz").then(function(e){return e.config.webPushNotifications})}function i(){return clients.matchAll({includeUncontrolled:!0}).then(function(e){return e.filter(function(e){var t=e.type;return"window"===t})})}var a=n(1),u=r(a);self.addEventListener("push",function(e){e.data&&e.waitUntil(o().then(function(t){return t&&i().then(function(t){var n=e.data.json();if(0===t.length)return self.registration.showNotification(n.title,n)})}))}),self.addEventListener("notificationclick",function(e){e.notification.close(),e.waitUntil(i().then(function(e){for(var t=0;t<e.length;t++){var n=e[t];if("/"===n.url&&"focus"in n)return n.focus()}if(clients.openWindow)return clients.openWindow("/")}))})},function(e,t){/*!
|
||||
localForage -- Offline Storage, Improved
|
||||
|
|
|
@ -22,6 +22,18 @@ test "turns hashtags into links" do
|
|||
assert expected_text ==
|
||||
Formatter.add_hashtag_links({[], text}, tags) |> Formatter.finalize()
|
||||
end
|
||||
|
||||
test "does not turn html characters to tags" do
|
||||
text = "Fact #3: pleroma does what mastodon't"
|
||||
|
||||
expected_text =
|
||||
"Fact <a data-tag='3' href='http://localhost:4001/tag/3' rel='tag'>#3</a>: pleroma does what mastodon't"
|
||||
|
||||
tags = Formatter.parse_tags(text)
|
||||
|
||||
assert expected_text ==
|
||||
Formatter.add_hashtag_links({[], text}, tags) |> Formatter.finalize()
|
||||
end
|
||||
end
|
||||
|
||||
describe ".add_links" do
|
||||
|
|
38
test/plugs/admin_secret_authentication_plug_test.exs
Normal file
38
test/plugs/admin_secret_authentication_plug_test.exs
Normal file
|
@ -0,0 +1,38 @@
|
|||
defmodule Pleroma.Plugs.AdminSecretAuthenticationPlugTest do
|
||||
use Pleroma.Web.ConnCase, async: true
|
||||
import Pleroma.Factory
|
||||
|
||||
alias Pleroma.Plugs.AdminSecretAuthenticationPlug
|
||||
|
||||
test "does nothing if a user is assigned", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> assign(:user, user)
|
||||
|
||||
ret_conn =
|
||||
conn
|
||||
|> AdminSecretAuthenticationPlug.call(%{})
|
||||
|
||||
assert conn == ret_conn
|
||||
end
|
||||
|
||||
test "with secret set and given in the 'admin_token' parameter, it assigns an admin user", %{
|
||||
conn: conn
|
||||
} do
|
||||
Pleroma.Config.put(:admin_token, "password123")
|
||||
|
||||
conn =
|
||||
%{conn | params: %{"admin_token" => "wrong_password"}}
|
||||
|> AdminSecretAuthenticationPlug.call(%{})
|
||||
|
||||
refute conn.assigns[:user]
|
||||
|
||||
conn =
|
||||
%{conn | params: %{"admin_token" => "password123"}}
|
||||
|> AdminSecretAuthenticationPlug.call(%{})
|
||||
|
||||
assert conn.assigns[:user].info.is_admin
|
||||
end
|
||||
end
|
|
@ -1,6 +1,8 @@
|
|||
defmodule Pleroma.Plugs.SetUserSessionIdPlugTest do
|
||||
use Pleroma.Web.ConnCase, async: true
|
||||
|
||||
Code.ensure_compiled(Pleroma.User)
|
||||
|
||||
alias Pleroma.Plugs.SetUserSessionIdPlug
|
||||
alias Pleroma.User
|
||||
|
||||
|
|
Loading…
Reference in a new issue