Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
a1batross
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
.
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