+14
-2
app/authenticator.rb
+14
-2
app/authenticator.rb
···
6
require 'openssl'
7
8
class Authenticator
9
def initialize(hostname:)
10
@@pkey_cache ||= {}
11
@hostname = hostname
···
15
return nil unless auth_header.start_with?('Bearer ')
16
17
token = auth_header.gsub(/\ABearer /, '')
18
-
data = JSON.parse(Base64.decode64(token.split('.')[1]))
19
did = data['iss']
20
-
return nil if data['aud'] != "did:web:#{@hostname}" || data['lxm'] != endpoint
21
22
pkey = pkey_for_user(did)
23
···
6
require 'openssl'
7
8
class Authenticator
9
+
class InvalidTokenError < StandardError
10
+
end
11
+
12
def initialize(hostname:)
13
@@pkey_cache ||= {}
14
@hostname = hostname
···
18
return nil unless auth_header.start_with?('Bearer ')
19
20
token = auth_header.gsub(/\ABearer /, '')
21
+
parts = token.split('.')
22
+
raise InvalidTokenError, "Invalid JWT token" if parts.length != 3
23
+
24
+
begin
25
+
decoded_data = Base64.decode64(parts[1])
26
+
data = JSON.parse(decoded_data)
27
+
rescue StandardError => e
28
+
raise InvalidTokenError, "Invalid JWT token"
29
+
end
30
+
31
did = data['iss']
32
+
return nil if did.nil? || data['aud'] != "did:web:#{@hostname}" || data['lxm'] != endpoint
33
34
pkey = pkey_for_user(did)
35
+43
-19
app/server.rb
+43
-19
app/server.rb
···
23
content_type :json
24
[status, JSON.generate({ error: name, message: message })]
25
end
26
end
27
28
before do
···
32
get '/xrpc/blue.feeds.lycan.searchPosts' do
33
headers['access-control-allow-origin'] = '*'
34
35
-
if settings.development?
36
-
user = User.find_by(did: params[:user])
37
-
return json_error('UserNotFound', 'Missing "user" parameter') if user.nil?
38
-
else
39
-
begin
40
-
auth_header = env['HTTP_AUTHORIZATION']
41
-
did = @authenticator.decode_user_from_jwt(auth_header, 'blue.feeds.lycan.searchPosts')
42
-
rescue StandardError => e
43
-
p e
44
-
end
45
-
46
-
user = did && User.find_by(did: did)
47
-
return json_error('UserNotFound', 'Missing authentication header') if user.nil?
48
-
end
49
50
if params[:query].to_s.strip.empty?
51
return json_error('MissingParameter', 'Missing "query" parameter')
···
58
query = QueryParser.new(params[:query])
59
60
collection = case params[:collection]
61
-
when 'likes' then user.likes
62
-
when 'pins' then user.pins
63
-
when 'quotes' then user.quotes
64
-
when 'reposts' then user.reposts
65
else return json_error('InvalidParameter', 'Invalid search collection')
66
end
67
···
80
81
post_uris = case params[:collection]
82
when 'quotes'
83
-
items.map { |x| "at://#{user.did}/app.bsky.feed.post/#{x.rkey}" }
84
else
85
items.map(&:post).map(&:at_uri)
86
end
···
23
content_type :json
24
[status, JSON.generate({ error: name, message: message })]
25
end
26
+
27
+
def get_user_did
28
+
if settings.development?
29
+
if did = params[:user]
30
+
return did
31
+
else
32
+
halt json_error('AuthMissing', 'Missing "user" parameter', status: 401)
33
+
end
34
+
else
35
+
auth_header = env['HTTP_AUTHORIZATION']
36
+
if auth_header.to_s.strip.empty?
37
+
halt json_error('AuthMissing', 'Missing authentication header', status: 401)
38
+
end
39
+
40
+
begin
41
+
did = @authenticator.decode_user_from_jwt(auth_header, 'blue.feeds.lycan.searchPosts')
42
+
rescue StandardError => e
43
+
halt json_error('InvalidToken', e.message, status: 401)
44
+
end
45
+
46
+
if did
47
+
return did
48
+
else
49
+
halt json_error('InvalidToken', "Invalid JWT token", status: 401)
50
+
end
51
+
end
52
+
end
53
+
54
+
def load_user
55
+
did = get_user_did
56
+
57
+
if user = User.find_by(did: did)
58
+
return user
59
+
else
60
+
halt json_error('AccountNotFound', 'Account not found', status: 401)
61
+
end
62
+
end
63
end
64
65
before do
···
69
get '/xrpc/blue.feeds.lycan.searchPosts' do
70
headers['access-control-allow-origin'] = '*'
71
72
+
@user = load_user
73
74
if params[:query].to_s.strip.empty?
75
return json_error('MissingParameter', 'Missing "query" parameter')
···
82
query = QueryParser.new(params[:query])
83
84
collection = case params[:collection]
85
+
when 'likes' then @user.likes
86
+
when 'pins' then @user.pins
87
+
when 'quotes' then @user.quotes
88
+
when 'reposts' then @user.reposts
89
else return json_error('InvalidParameter', 'Invalid search collection')
90
end
91
···
104
105
post_uris = case params[:collection]
106
when 'quotes'
107
+
items.map { |x| "at://#{@user.did}/app.bsky.feed.post/#{x.rkey}" }
108
else
109
items.map(&:post).map(&:at_uri)
110
end