Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Alex Gleason
pleroma
Commits
3dd6bd4b
Commit
3dd6bd4b
authored
May 16, 2017
by
dtluna
Browse files
wip
parent
6a3efd27
Changes
18
Hide whitespace changes
Inline
Side-by-side
lib/pleroma/application.ex
View file @
3dd6bd4b
...
...
@@ -15,7 +15,7 @@ defmodule Pleroma.Application do
# Start your own worker by calling: Pleroma.Worker.start_link(arg1, arg2, arg3)
# worker(Pleroma.Worker, [arg1, arg2, arg3]),
worker
(
Cachex
,
[
:user_cache
,
[
default_ttl:
25000
,
default_ttl:
25
_
000
,
ttl_interval:
1000
,
limit:
2500
]]),
...
...
lib/pleroma/user.ex
View file @
3dd6bd4b
...
...
@@ -123,10 +123,10 @@ defmodule Pleroma.User do
following
=
follower
.
following
|>
List
.
delete
(
ap_followers
)
{
:ok
,
follower
}
=
follower
{
:ok
,
follower
}
=
follower
|>
follow_changeset
(%{
following:
following
})
|>
Repo
.
update
{
:ok
,
follower
,
ActivityPub
.
fetch_latest_follow
(
follower
,
followed
)}
{
:ok
,
follower
,
ActivityPub
.
fetch_latest_follow
(
follower
,
followed
)}
else
{
:error
,
"Not subscribed!"
}
end
...
...
lib/pleroma/web/activity_pub/activity_pub.ex
View file @
3dd6bd4b
...
...
@@ -101,7 +101,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
end
)
end
def
unlike
(%
User
{
ap_id:
ap_id
},
%
Object
{
data:
%{
"id"
=>
id
}}
=
object
)
do
def
unlike
(%
User
{
ap_id:
ap_id
},
%
Object
{
data:
%{
"id"
=>
id
}}
=
object
)
do
query
=
from
activity
in
Activity
,
where:
fragment
(
"? @> ?"
,
activity
.
data
,
^
%{
actor:
ap_id
,
object:
id
,
type:
"Like"
})
...
...
@@ -157,7 +157,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
order_by:
[
desc:
:inserted_at
]
query
=
Enum
.
reduce
(
recipients
,
query
,
fn
(
recipient
,
q
)
->
map
=
%{
to:
[
recipient
]
}
map
=
%{
to:
[
recipient
]}
from
activity
in
q
,
or_where:
fragment
(
~s(? @> ?)
,
activity
.
data
,
^
map
)
end
)
...
...
@@ -258,7 +258,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
def
fetch_activities_for_context
(
context
)
do
query
=
from
activity
in
Activity
,
where:
fragment
(
"? @> ?"
,
activity
.
data
,
^
%{
context:
context
})
where:
fragment
(
"? @> ?"
,
activity
.
data
,
^
%{
context:
context
})
Repo
.
all
(
query
)
end
...
...
lib/pleroma/web/ostatus/ostatus.ex
View file @
3dd6bd4b
...
...
@@ -99,7 +99,8 @@ defmodule Pleroma.Web.OStatus do
end
def
get_attachments
(
entry
)
do
:xmerl_xpath
.
string
(
'/entry/link[@rel="enclosure"]'
,
entry
)
xpath
=
:xmerl_xpath
.
string
(
'/entry/link[@rel="enclosure"]'
,
entry
)
xpath
|>
Enum
.
map
(
fn
(
enclosure
)
->
with
href
when
not
is_nil
(
href
)
<-
string_from_xpath
(
"/link/@href"
,
enclosure
),
type
when
not
is_nil
(
type
)
<-
string_from_xpath
(
"/link/@type"
,
enclosure
)
do
...
...
@@ -121,12 +122,12 @@ defmodule Pleroma.Web.OStatus do
[
author
]
=
:xmerl_xpath
.
string
(
'//author[1]'
,
doc
)
{
:ok
,
actor
}
=
find_make_or_update_user
(
author
)
in
R
eply
T
o
=
string_from_xpath
(
"//thr:in-reply-to[1]/@ref"
,
entry
)
in
_r
eply
_t
o
=
string_from_xpath
(
"//thr:in-reply-to[1]/@ref"
,
entry
)
if
!Object
.
get_cached_by_ap_id
(
in
R
eply
T
o
)
do
in
R
eply
ToH
ref
=
string_from_xpath
(
"//thr:in-reply-to[1]/@href"
,
entry
)
if
in
R
eply
ToH
ref
do
fetch_activity_from_html_url
(
in
R
eply
ToH
ref
)
if
!Object
.
get_cached_by_ap_id
(
in
_r
eply
_t
o
)
do
in
_r
eply
_to_h
ref
=
string_from_xpath
(
"//thr:in-reply-to[1]/@href"
,
entry
)
if
in
_r
eply
_to_h
ref
do
fetch_activity_from_html_url
(
in
_r
eply
_to_h
ref
)
end
end
...
...
@@ -134,7 +135,7 @@ defmodule Pleroma.Web.OStatus do
attachments
=
get_attachments
(
entry
)
context
=
with
%{
data:
%{
"context"
=>
context
}}
<-
Object
.
get_cached_by_ap_id
(
in
R
eply
T
o
)
do
context
=
with
%{
data:
%{
"context"
=>
context
}}
<-
Object
.
get_cached_by_ap_id
(
in
_r
eply
_t
o
)
do
context
else
_e
->
if
String
.
length
(
context
)
>
0
do
...
...
@@ -148,8 +149,8 @@ defmodule Pleroma.Web.OStatus do
"https://www.w3.org/ns/activitystreams#Public"
,
User
.
ap_followers
(
actor
)
]
mentions
=
:xmerl_xpath
.
string
(
'//link[@rel="mentioned" and @ostatus:object-type="http://activitystrea.ms/schema/1.0/person"]'
,
entry
)
xpath
=
:xmerl_xpath
.
string
(
'//link[@rel="mentioned" and @ostatus:object-type="http://activitystrea.ms/schema/1.0/person"]'
,
entry
)
mentions
=
xpath
|>
Enum
.
map
(
fn
(
person
)
->
string_from_xpath
(
"@href"
,
person
)
end
)
to
=
to
++
mentions
...
...
@@ -168,8 +169,8 @@ defmodule Pleroma.Web.OStatus do
"attachment"
=>
attachments
}
object
=
if
in
R
eply
T
o
do
Map
.
put
(
object
,
"inReplyTo"
,
in
R
eply
T
o
)
object
=
if
in
_r
eply
_t
o
do
Map
.
put
(
object
,
"inReplyTo"
,
in
_r
eply
_t
o
)
else
object
end
...
...
@@ -245,7 +246,7 @@ defmodule Pleroma.Web.OStatus do
def
gather_user_info
(
username
)
do
with
{
:ok
,
webfinger_data
}
<-
WebFinger
.
finger
(
username
),
{
:ok
,
feed_data
}
<-
Websub
.
gather_feed_data
(
webfinger_data
[
"topic"
])
do
{
:ok
,
Map
.
merge
(
webfinger_data
,
feed_data
)
|>
Map
.
put
(
"fqn"
,
username
)}
{
:ok
,
webfinger_data
|>
Map
.
merge
(
feed_data
)
|>
Map
.
put
(
"fqn"
,
username
)}
else
e
->
Logger
.
debug
(
fn
->
"Couldn't gather info for
#{
username
}
"
end
)
{
:error
,
e
}
...
...
lib/pleroma/web/salmon/salmon.ex
View file @
3dd6bd4b
...
...
@@ -67,8 +67,8 @@ defmodule Pleroma.Web.Salmon do
end
def
encode_key
({
:RSAPublicKey
,
modulus
,
exponent
})
do
modulus_enc
=
:binary
.
encode_unsigned
(
modulus
)
|>
Base
.
url_encode64
exponent_enc
=
:binary
.
encode_unsigned
(
exponent
)
|>
Base
.
url_encode64
modulus_enc
=
modulus
|>
:binary
.
encode_unsigned
|>
Base
.
url_encode64
exponent_enc
=
exponent
|>
:binary
.
encode_unsigned
|>
Base
.
url_encode64
"RSA.
#{
modulus_enc
}
.
#{
exponent_enc
}
"
end
...
...
@@ -139,7 +139,8 @@ defmodule Pleroma.Web.Salmon do
def
publish
(
user
,
activity
,
poster
\\
&
@httpoison
.
post
/
3
)
def
publish
(%{
info:
%{
"keys"
=>
keys
}}
=
user
,
activity
,
poster
)
do
feed
=
ActivityRepresenter
.
to_simple_form
(
activity
,
user
,
true
)
feed
=
activity
|>
ActivityRepresenter
.
to_simple_form
(
user
,
true
)
|>
ActivityRepresenter
.
wrap_with_entry
|>
:xmerl
.
export_simple
(
:xmerl_xml
)
|>
to_string
...
...
@@ -148,7 +149,8 @@ defmodule Pleroma.Web.Salmon do
{
:ok
,
private
,
_
}
=
keys_from_pem
(
keys
)
{
:ok
,
feed
}
=
encode
(
private
,
feed
)
remote_users
(
activity
)
activity
|>
remote_users
|>
Enum
.
each
(
fn
(
remote_user
)
->
Task
.
start
(
fn
->
Logger
.
debug
(
fn
->
"sending salmon to
#{
remote_user
.
ap_id
}
"
end
)
...
...
lib/pleroma/web/twitter_api/controllers/status_controller.ex
View file @
3dd6bd4b
...
...
@@ -84,6 +84,8 @@ defmodule Pleroma.Web.TwitterAPI.StatusController do
end
end
#TODO: DRY the code
def
favorite
(%{
assigns:
%{
user:
user
}}
=
conn
,
%{
"id"
=>
id
})
do
case
find_activity
(
conn
,
id
)
do
{
:not_found
,
response
}
->
response
...
...
lib/pleroma/web/twitter_api/controllers/user_controller.ex
View file @
3dd6bd4b
...
...
@@ -9,6 +9,8 @@ defmodule Pleroma.Web.TwitterAPI.UserController do
render
conn
,
"show.json"
,
%{
user:
user
,
for:
user
}
end
#TODO: DRY the code
def
follow
(%{
assigns:
%{
user:
follower
}}
=
conn
,
params
)
do
case
find_user
(
conn
,
params
)
do
{
:ok
,
followed
=
%
User
{}}
->
...
...
lib/pleroma/web/twitter_api/twitter_api.ex
View file @
3dd6bd4b
...
...
@@ -12,7 +12,8 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do
end
def
format_input
(
text
,
mentions
)
do
HtmlSanitizeEx
.
strip_tags
(
text
)
text
|>
HtmlSanitizeEx
.
strip_tags
|>
String
.
replace
(
"
\n
"
,
"<br>"
)
|>
add_user_links
(
mentions
)
end
...
...
@@ -49,13 +50,13 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do
to
=
to_for_user_and_mentions
(
user
,
mentions
)
date
=
Misc
.
make_date
()
in
R
eply
T
o
=
get_replied_to_activity
(
data
[
"in_reply_to_status_id"
])
in
_r
eply
_t
o
=
get_replied_to_activity
(
data
[
"in_reply_to_status_id"
])
# Wire up reply info.
[
to
,
context
,
object
,
additional
]
=
if
in
R
eply
T
o
do
context
=
in
R
eply
T
o
.
data
[
"context"
]
to
=
to
++
[
in
R
eply
T
o
.
data
[
"actor"
]]
if
in
_r
eply
_t
o
do
context
=
in
_r
eply
_t
o
.
data
[
"context"
]
to
=
to
++
[
in
_r
eply
_t
o
.
data
[
"actor"
]]
object
=
%{
"type"
=>
"Note"
,
...
...
@@ -65,8 +66,8 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do
"context"
=>
context
,
"attachment"
=>
attachments
,
"actor"
=>
user
.
ap_id
,
"inReplyTo"
=>
in
R
eply
T
o
.
data
[
"object"
][
"id"
],
"inReplyToStatusId"
=>
in
R
eply
T
o
.
id
,
"inReplyTo"
=>
in
_r
eply
_t
o
.
data
[
"object"
][
"id"
],
"inReplyToStatusId"
=>
in
_r
eply
_t
o
.
id
,
}
additional
=
%{}
...
...
@@ -91,7 +92,8 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do
# Modified from https://www.w3.org/TR/html5/forms.html#valid-e-mail-address
regex
=
~r/@[a-zA-Z0-9.!#$%&'*+\/
=
?^
_
`
{
|
}
~
-
]
+
@
?[
a
-
zA
-
Z0
-
9
](
?:
[
a
-
zA
-
Z0
-
9
-
]{
0
,
61
}[
a
-
zA
-
Z0
-
9
])
?(?:
\
.
[
a
-
zA
-
Z0
-
9
](
?:
[
a
-
zA
-
Z0
-
9
-
]{
0
,
61
}[
a
-
zA
-
Z0
-
9
])
?)
*/
Regex
.
scan
(
regex
,
text
)
regex
|>
Regex
.
scan
(
text
)
|>
List
.
flatten
|>
Enum
.
uniq
|>
Enum
.
map
(
fn
(
"@"
<>
match
=
full_match
)
->
{
full_match
,
User
.
get_cached_by_nickname
(
match
)}
end
)
...
...
lib/pleroma/web/twitter_api/views/status_view.ex
View file @
3dd6bd4b
...
...
@@ -6,11 +6,11 @@ defmodule Pleroma.Web.TwitterAPI.StatusView do
def
render
(
"show.json"
,
assigns
=
%{
%{
activity:
%
Activity
{
data:
%{
"type"
=>
"Announce"
,
"id"
=>
id
,
"object"
=>
ap_id
}
},
})
do
}
=
assigns
)
do
{
activity
,
user
}
=
render_activity
(
assigns
)
[
announced_activity
=
%
Activity
{}]
=
Activity
.
all_by_object_ap_id
(
ap_id
)
...
...
@@ -29,10 +29,10 @@ defmodule Pleroma.Web.TwitterAPI.StatusView do
def
render
(
"show.json"
,
assigns
=
%{
activity:
%
Activity
{
%{
activity:
%
Activity
{
data:
%{
"type"
=>
"Like"
,
"id"
=>
id
,
"object"
=>
liked_id
}
},
})
do
}
=
assigns
)
do
{
activity
,
%
User
{
nickname:
nickname
}}
=
render_activity
(
assigns
)
text
=
"
#{
nickname
}
favorited a status."
[%
Activity
{
id:
liked_activity_id
}]
=
Activity
.
all_by_object_ap_id
(
liked_id
)
...
...
@@ -47,11 +47,11 @@ defmodule Pleroma.Web.TwitterAPI.StatusView do
def
render
(
"show.json"
,
assigns
=
%{
%{
activity:
%
Activity
{
data:
%{
"type"
=>
"Follow"
,
"object"
=>
followed_id
}
}
}
}
=
assigns
)
do
{
activity
,
%
User
{
nickname:
follower_name
}}
=
render_activity
(
assigns
)
%
User
{
nickname:
followed_name
}
=
User
.
get_cached_by_ap_id
(
followed_id
)
...
...
@@ -65,16 +65,16 @@ defmodule Pleroma.Web.TwitterAPI.StatusView do
def
render
(
"show.json"
,
assigns
=
%{
%{
activity:
%
Activity
{
data:
%{
"type"
=>
"Create"
,
"to"
=>
to
,
"object"
=>
object
=
%{
"object"
=>
%{
"content"
=>
content
}
}
=
object
}
}
}
}
=
assigns
)
do
announcement_count
=
object
[
"announcement_count"
]
||
0
repeated
=
Misc
.
to_boolean
(
assigns
[
:for
]
&&
assigns
[
:for
]
.
ap_id
in
(
object
[
"announcements"
]
||
[]))
...
...
@@ -107,7 +107,7 @@ defmodule Pleroma.Web.TwitterAPI.StatusView do
})
end
def
render
(
"timeline.json"
,
assigns
=
%{
activities:
activities
})
do
def
render
(
"timeline.json"
,
%{
activities:
activities
}
=
assigns
)
do
render_many
(
activities
,
Pleroma
.
Web
.
TwitterAPI
.
StatusView
,
"show.json"
,
Map
.
merge
(
assigns
,
%{
as:
:activity
}))
end
...
...
lib/pleroma/web/twitter_api/views/user_view.ex
View file @
3dd6bd4b
...
...
@@ -2,7 +2,7 @@ defmodule Pleroma.Web.TwitterAPI.UserView do
use
Pleroma
.
Web
,
:view
alias
Pleroma
.
User
def
render
(
"show.json"
,
assigns
=
%{
user:
user
=
%
User
{}})
do
def
render
(
"show.json"
,
%{
user:
user
=
%
User
{}}
=
assigns
)
do
image
=
User
.
avatar_url
(
user
)
following
=
if
assigns
[
:for
]
do
User
.
following?
(
assigns
[
:for
],
user
)
...
...
lib/pleroma/web/websub/websub.ex
View file @
3dd6bd4b
...
...
@@ -61,7 +61,8 @@ defmodule Pleroma.Web.Websub do
end
def
sign
(
secret
,
doc
)
do
:crypto
.
hmac
(
:sha
,
secret
,
to_string
(
doc
))
|>
Base
.
encode16
|>
String
.
downcase
encrypted_secret
=
:crypto
.
hmac
(
:sha
,
secret
,
to_string
(
doc
))
encrypted_secret
|>
Base
.
encode16
|>
String
.
downcase
end
def
incoming_subscription_request
(
user
,
%{
"hub.mode"
=>
"subscribe"
}
=
params
)
do
...
...
@@ -135,7 +136,7 @@ defmodule Pleroma.Web.Websub do
hub:
subscribed
.
info
[
"hub"
],
subscribers:
[
subscriber
.
ap_id
],
state:
"requested"
,
secret:
:crypto
.
strong_rand_bytes
(
8
)
|>
Base
.
url_encode64
,
secret:
Base
.
url_encode64
(
:crypto
.
strong_rand_bytes
(
8
)
)
,
user:
subscribed
}
Repo
.
insert
(
subscription
)
...
...
@@ -152,15 +153,15 @@ defmodule Pleroma.Web.Websub do
hub
when
not
is_nil
(
hub
)
<-
XML
.
string_from_xpath
(
~S{/feed/link[@rel="hub"]/@href}
,
doc
)
do
name
=
XML
.
string_from_xpath
(
"/feed/author[1]/name"
,
doc
)
preferred
U
sername
=
XML
.
string_from_xpath
(
"/feed/author[1]/poco:preferredUsername"
,
doc
)
display
N
ame
=
XML
.
string_from_xpath
(
"/feed/author[1]/poco:displayName"
,
doc
)
preferred
_u
sername
=
XML
.
string_from_xpath
(
"/feed/author[1]/poco:preferredUsername"
,
doc
)
display
_n
ame
=
XML
.
string_from_xpath
(
"/feed/author[1]/poco:displayName"
,
doc
)
avatar
=
OStatus
.
make_avatar_object
(
doc
)
{
:ok
,
%{
"uri"
=>
uri
,
"hub"
=>
hub
,
"nickname"
=>
preferred
U
sername
||
name
,
"name"
=>
display
N
ame
||
name
,
"nickname"
=>
preferred
_u
sername
||
name
,
"name"
=>
display
_n
ame
||
name
,
"host"
=>
URI
.
parse
(
uri
)
.
host
,
"avatar"
=>
avatar
}}
...
...
test/object_test.exs
View file @
3dd6bd4b
...
...
@@ -16,7 +16,7 @@ defmodule Pleroma.ObjectTest do
cs
=
Object
.
change
(%
Object
{},
%{
data:
%{
id:
object
.
data
[
"id"
]}})
assert
cs
.
valid?
{
:error
,
result
}
=
Repo
.
insert
(
cs
)
{
:error
,
_
result
}
=
Repo
.
insert
(
cs
)
end
end
end
test/user_test.exs
View file @
3dd6bd4b
...
...
@@ -9,11 +9,6 @@ defmodule Pleroma.UserTest do
import
Ecto
.
Query
test
"ap_id returns the activity pub id for the user"
do
host
=
Application
.
get_env
(
:pleroma
,
Pleroma
.
Web
.
Endpoint
)
|>
Keyword
.
fetch!
(
:url
)
|>
Keyword
.
fetch!
(
:host
)
user
=
UserBuilder
.
build
expected_ap_id
=
"
#{
Pleroma
.
Web
.
base_url
}
/users/
#{
user
.
nickname
}
"
...
...
test/web/ostatus/activity_representer_test.exs
View file @
3dd6bd4b
...
...
@@ -80,7 +80,7 @@ defmodule Pleroma.Web.OStatus.ActivityRepresenterTest do
user
=
insert
(
:user
)
object
=
Object
.
get_cached_by_ap_id
(
note
.
data
[
"object"
][
"id"
])
{
:ok
,
announce
,
object
}
=
ActivityPub
.
announce
(
user
,
object
)
{
:ok
,
announce
,
_
object
}
=
ActivityPub
.
announce
(
user
,
object
)
announce
=
Repo
.
get
(
Activity
,
announce
.
id
)
...
...
test/web/salmon/salmon_test.exs
View file @
3dd6bd4b
...
...
@@ -84,7 +84,7 @@ defmodule Pleroma.Web.Salmon.SalmonTest do
user
=
Repo
.
get_by
(
User
,
ap_id:
activity
.
data
[
"actor"
])
{
:ok
,
user
}
=
Pleroma
.
Web
.
WebFinger
.
ensure_keys_present
(
user
)
poster
=
fn
(
url
,
data
,
headers
)
->
poster
=
fn
(
url
,
_
data
,
_
headers
)
->
assert
url
==
"http://example.org/salmon"
end
Salmon
.
publish
(
user
,
activity
,
poster
)
...
...
test/web/twitter_api/twitter_api_controller_test.exs
View file @
3dd6bd4b
...
...
@@ -7,6 +7,8 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
import
Pleroma
.
Factory
# TODO: separate into individual controller tests
describe
"POST /api/account/verify_credentials"
do
setup
[
:valid_user
]
test
"without valid credentials"
,
%{
conn:
conn
}
do
...
...
test/web/twitter_api/views/status_view_test.exs
View file @
3dd6bd4b
...
...
@@ -3,7 +3,6 @@ defmodule Pleroma.Web.TwitterAPI.Representers.ActivityRepresenterTest do
alias
Pleroma
.
{
User
,
Activity
,
Object
}
alias
Pleroma
.
Web
.
TwitterAPI
.
{
AttachmentView
,
UserView
,
StatusView
}
alias
Pleroma
.
Web
.
ActivityPub
.
ActivityPub
alias
Pleroma
.
Builders
.
UserBuilder
import
Pleroma
.
Factory
test
"an announce activity"
do
...
...
@@ -45,7 +44,7 @@ defmodule Pleroma.Web.TwitterAPI.Representers.ActivityRepresenterTest do
end
test
"an activity"
do
{
:ok
,
user
}
=
U
ser
Builder
.
insert
user
=
in
ser
t
(
:user
,
%{
nickname:
"dtluna"
})
# {:ok, mentioned_user } = UserBuilder.insert(%{nickname: "shp", ap_id: "shp"})
mentioned_user
=
insert
(
:user
,
%{
nickname:
"shp"
})
...
...
@@ -105,7 +104,6 @@ defmodule Pleroma.Web.TwitterAPI.Representers.ActivityRepresenterTest do
"id"
=>
activity
.
id
,
"user"
=>
UserView
.
render
(
"show.json"
,
%{
user:
user
,
for:
follower
}),
"is_local"
=>
true
,
"attentions"
=>
[],
"statusnet_html"
=>
content_html
,
"text"
=>
content
,
"is_post_verb"
=>
true
,
...
...
test/web/websub/websub_test.exs
View file @
3dd6bd4b
...
...
@@ -172,6 +172,6 @@ defmodule Pleroma.Web.WebsubTest do
signed
=
Websub
.
sign
(
"secret"
,
"text"
)
assert
signed
==
"B8392C23690CCF871F37EC270BE1582DEC57A503"
|>
String
.
downcase
signed
=
Websub
.
sign
(
"secret"
,
[[
"て"
],
[
'す'
]])
Websub
.
sign
(
"secret"
,
[[
"て"
],
[
'す'
]])
end
end
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment