tangled
alpha
login
or
join now
futur.blue
/
pegasus
56
fork
atom
objective categorical abstract machine language personal data server
56
fork
atom
overview
issues
2
pulls
pipelines
xrpc createInviteCode
futur.blue
6 months ago
bd83727d
3699b4cb
verified
This commit was signed with the committer's
known signature
.
futur.blue
SSH Key Fingerprint:
SHA256:QHGqHWNpqYyw9bt8KmPuJIyeZX9SZewBZ0PR1COtKQ0=
+94
-8
4 changed files
expand all
collapse all
unified
split
bin
main.ml
pegasus
lib
api
repo
createAccount.ml
server
createInviteCode.ml
data_store.ml
+11
-5
bin/main.ml
···
11
( get
12
, "/xrpc/com.atproto.server.describeServer"
13
, Api.Server.DescribeServer.handler )
0
14
; ( get
15
, "/xrpc/com.atproto.identity.resolveHandle"
16
, Api.Identity.ResolveHandle.handler )
0
0
0
0
0
0
0
17
; ( post
18
, "/xrpc/com.atproto.server.createSession"
19
, Api.Server.CreateSession.handler )
20
-
; (get, "/xrpc/com.atproto.repo.getRecord", Api.Repo.GetRecord.handler)
21
-
; (get, "/xrpc/com.atproto.repo.listRecords", Api.Repo.ListRecords.handler)
22
-
; (get, "/xrpc/com.atproto.repo.describeRepo", Api.Repo.DescribeRepo.handler)
23
-
; (* account *)
24
-
(get, "/xrpc/com.atproto.server.getSession", Api.Server.GetSession.handler)
25
; ( post
26
, "/xrpc/com.atproto.server.refreshSession"
27
, Api.Server.RefreshSession.handler )
···
35
(post, "/xrpc/com.atproto.repo.applyWrites", Api.Repo.ApplyWrites.handler)
36
; (post, "/xrpc/com.atproto.repo.createRecord", Api.Repo.CreateRecord.handler)
37
; (post, "/xrpc/com.atproto.repo.putRecord", Api.Repo.PutRecord.handler)
0
0
38
; (post, "/xrpc/com.atproto.repo.deleteRecord", Api.Repo.DeleteRecord.handler)
39
; (post, "/xrpc/com.atproto.repo.uploadBlob", Api.Repo.UploadBlob.handler)
40
; (* sync *)
···
11
( get
12
, "/xrpc/com.atproto.server.describeServer"
13
, Api.Server.DescribeServer.handler )
14
+
; (get, "/xrpc/com.atproto.repo.describeRepo", Api.Repo.DescribeRepo.handler)
15
; ( get
16
, "/xrpc/com.atproto.identity.resolveHandle"
17
, Api.Identity.ResolveHandle.handler )
18
+
; (* account *)
19
+
( post
20
+
, "/xrpc/com.atproto.server.createInviteCode"
21
+
, Api.Server.CreateInviteCode.handler )
22
+
; ( post
23
+
, "/xrpc/com.atproto.repo.createAccount"
24
+
, Api.Repo.CreateAccount.handler )
25
; ( post
26
, "/xrpc/com.atproto.server.createSession"
27
, Api.Server.CreateSession.handler )
28
+
; (get, "/xrpc/com.atproto.server.getSession", Api.Server.GetSession.handler)
0
0
0
0
29
; ( post
30
, "/xrpc/com.atproto.server.refreshSession"
31
, Api.Server.RefreshSession.handler )
···
39
(post, "/xrpc/com.atproto.repo.applyWrites", Api.Repo.ApplyWrites.handler)
40
; (post, "/xrpc/com.atproto.repo.createRecord", Api.Repo.CreateRecord.handler)
41
; (post, "/xrpc/com.atproto.repo.putRecord", Api.Repo.PutRecord.handler)
42
+
; (get, "/xrpc/com.atproto.repo.getRecord", Api.Repo.GetRecord.handler)
43
+
; (get, "/xrpc/com.atproto.repo.listRecords", Api.Repo.ListRecords.handler)
44
; (post, "/xrpc/com.atproto.repo.deleteRecord", Api.Repo.DeleteRecord.handler)
45
; (post, "/xrpc/com.atproto.repo.uploadBlob", Api.Repo.UploadBlob.handler)
46
; (* sync *)
+27
-3
pegasus/lib/api/repo/createAccount.ml
···
17
let handler =
18
Xrpc.handler (fun ctx ->
19
let%lwt input = Xrpc.parse_body ctx.req request_of_yojson in
20
-
if input.invite_code = None && Env.invite_required = true then
21
-
Errors.invalid_request ~name:"InvalidInviteCode"
22
-
"no invite code provided" ;
0
0
0
0
0
0
0
0
0
0
0
0
0
23
let () =
24
match Util.validate_handle input.handle with
25
| Ok _ ->
···
69
Lwt.return did
70
| Error e ->
71
failwith e )
0
0
0
0
0
0
0
0
0
0
0
72
in
73
let sk_priv_mk = Kleidos.P256.privkey_to_multikey signing_key in
74
let%lwt () =
···
17
let handler =
18
Xrpc.handler (fun ctx ->
19
let%lwt input = Xrpc.parse_body ctx.req request_of_yojson in
20
+
let%lwt () =
21
+
match input.invite_code with
22
+
| None when Env.invite_required = true ->
23
+
Errors.invalid_request ~name:"InvalidInviteCode"
24
+
"no invite code provided"
25
+
| Some code when Env.invite_required = true -> (
26
+
let%lwt invite = Data_store.get_invite ~code ctx.db in
27
+
match invite with
28
+
| Some i when i.remaining > 0 ->
29
+
Lwt.return_unit
30
+
| _ ->
31
+
Errors.invalid_request ~name:"InvalidInviteCode"
32
+
"invalid invite code" )
33
+
| _ ->
34
+
Lwt.return_unit
35
+
in
36
let () =
37
match Util.validate_handle input.handle with
38
| Ok _ ->
···
82
Lwt.return did
83
| Error e ->
84
failwith e )
85
+
in
86
+
let%lwt _ =
87
+
match input.invite_code with
88
+
| Some code -> (
89
+
match%lwt Data_store.use_invite ~code ctx.db with
90
+
| Some _ ->
91
+
Lwt.return ()
92
+
| None ->
93
+
failwith "failed to use invite code" )
94
+
| None ->
95
+
Lwt.return ()
96
in
97
let sk_priv_mk = Kleidos.P256.privkey_to_multikey signing_key in
98
let%lwt () =
+22
pegasus/lib/api/server/createInviteCode.ml
···
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
···
1
+
type request =
2
+
{ use_count: int [@key "useCount"]
3
+
; for_account: string option [@key "forAccount"] }
4
+
[@@deriving yojson]
5
+
6
+
type response = {code: string} [@@deriving yojson]
7
+
8
+
let handler =
9
+
Xrpc.handler ~auth:Auth.Verifiers.admin (fun {req; db; _} ->
10
+
let%lwt {use_count; for_account} =
11
+
Xrpc.parse_body req request_of_yojson
12
+
in
13
+
let remaining = Int.max 1 (Int.min use_count 5) in
14
+
let did = Option.value for_account ~default:"admin" in
15
+
let code =
16
+
String.sub
17
+
Digestif.SHA256.(
18
+
digest_string (did ^ Int.to_string @@ Util.now_ms ()) |> to_hex )
19
+
0 8
20
+
in
21
+
let%lwt () = Data_store.create_invite ~code ~did ~remaining db in
22
+
Dream.json @@ Yojson.Safe.to_string @@ response_to_yojson {code} )
+34
pegasus/lib/data_store.ml
···
13
; created_at: int
14
; deactivated_at: int option }
15
0
0
16
type firehose_event = {seq: int; time: int; t: string; data: bytes}
17
end
18
···
131
{sql| UPDATE actors SET preferences = %Json{preferences} WHERE did = %string{did}
132
|sql}]
133
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
134
(* firehose *)
135
let firehose_insert =
136
[%rapper
···
228
229
let put_preferences ~did ~prefs conn =
230
unwrap @@ Queries.put_preferences ~did ~preferences:prefs conn
0
0
0
0
0
0
0
0
231
232
(* firehose helpers *)
233
let append_firehose_event conn ~time ~t ~data : int Lwt.t =
···
13
; created_at: int
14
; deactivated_at: int option }
15
16
+
type invite_code = {code: string; did: string; remaining: int}
17
+
18
type firehose_event = {seq: int; time: int; t: string; data: bytes}
19
end
20
···
133
{sql| UPDATE actors SET preferences = %Json{preferences} WHERE did = %string{did}
134
|sql}]
135
136
+
(* invites *)
137
+
let create_invite =
138
+
[%rapper
139
+
execute
140
+
{sql| INSERT INTO invite_codes (code, did, remaining)
141
+
VALUES (%string{code}, %string{did}, %int{remaining})
142
+
|sql}]
143
+
144
+
let get_invite =
145
+
[%rapper
146
+
get_opt
147
+
{sql| SELECT @string{code}, @string{did}, @int{remaining}
148
+
FROM invite_codes WHERE code = %string{code}
149
+
|sql}
150
+
record_out]
151
+
152
+
let use_invite =
153
+
[%rapper
154
+
get_opt
155
+
{sql| UPDATE invite_codes SET remaining = remaining - 1
156
+
WHERE code = %string{code} AND remaining > 0
157
+
RETURNING @int{remaining}
158
+
|sql}]
159
+
160
(* firehose *)
161
let firehose_insert =
162
[%rapper
···
254
255
let put_preferences ~did ~prefs conn =
256
unwrap @@ Queries.put_preferences ~did ~preferences:prefs conn
257
+
258
+
(* invite codes *)
259
+
let create_invite ~code ~did ~remaining conn =
260
+
unwrap @@ Queries.create_invite ~code ~did ~remaining conn
261
+
262
+
let get_invite ~code conn = unwrap @@ Queries.get_invite ~code conn
263
+
264
+
let use_invite ~code conn = unwrap @@ Queries.use_invite ~code conn
265
266
(* firehose helpers *)
267
let append_firehose_event conn ~time ~t ~data : int Lwt.t =