objective categorical abstract machine language personal data server
65
fork

Configure Feed

Select the types of activity you want to include in your feed.

Permissions page fixes

futurGH 862a8ae1 3b297ace

+20 -15
+3 -10
frontend/src/templates/AccountPermissionsPage.mlx
··· 16 16 type device = 17 17 { last_ip: string 18 18 ; last_user_agent: string option [@default None] 19 - ; last_refreshed_at: int 19 + ; last_refreshed_at: string 20 20 ; is_current: bool } 21 21 [@@deriving json] 22 22 ··· 61 61 else "Unknown Browser" 62 62 else "Unknown Browser" 63 63 in 64 - os ^ " · " ^ browser 65 - 66 - let format_date timestamp_ms = 67 - let date = Js.Date.fromFloat (float_of_int timestamp_ms) in 68 - let month = Js.Date.getMonth date |> int_of_float in 69 - let day = Js.Date.getDate date |> int_of_float in 70 - let year = Js.Date.getFullYear date |> int_of_float in 71 - Printf.sprintf "%d/%d/%d" year (month + 1) day 64 + os ^ " \u{B7} " ^ browser 72 65 73 66 let[@react.component] make 74 67 ~props: ··· 180 173 </div> 181 174 <span className="text-sm text-mist-80"> 182 175 (string 183 - ( format_date device.last_refreshed_at 176 + ( device.last_refreshed_at 184 177 ^ " from " ^ device.last_ip ) ) 185 178 </span> 186 179 </li> )
+8 -2
pegasus/lib/api/account_/permissions.ml
··· 1 + let format_date timestamp_ms = 2 + let ts = float_of_int timestamp_ms /. 1000.0 in 3 + let dt = Timedesc.of_timestamp_float_s_exn ts in 4 + Format.asprintf "%a" (Timedesc.pp ~format:"{year}/{mon:0X}/{day:0X}" ()) dt 5 + 1 6 let get_client_host client_id = 2 7 let uri = Uri.of_string client_id in 3 8 Uri.host uri |> Option.value ~default:client_id ··· 47 52 let%lwt device_rows = 48 53 Oauth.Queries.get_distinct_devices_by_did ctx.db did 49 54 in 50 - let current_ip = Dream.client ctx.req in 55 + let current_ip = Util.request_ip ctx.req in 51 56 let current_ua = Dream.header ctx.req "User-Agent" in 52 57 let devices = 53 58 List.map 54 - (fun (last_ip, last_user_agent, last_refreshed_at) -> 59 + (fun (last_ip, last_user_agent, last_refreshed_ms) -> 55 60 let is_current = 56 61 last_ip = current_ip && last_user_agent = current_ua 57 62 in 63 + let last_refreshed_at = format_date last_refreshed_ms in 58 64 ( {last_ip; last_user_agent; last_refreshed_at; is_current} 59 65 : Frontend.AccountPermissionsPage.device ) ) 60 66 device_rows
+1 -1
pegasus/lib/api/oauth_/token.ml
··· 4 4 Xrpc.handler ~auth:DPoP (fun ctx -> 5 5 let%lwt req = Xrpc.parse_body ctx.req Types.token_request_of_yojson in 6 6 let proof = Auth.get_dpop_proof_exn ctx.auth in 7 - let ip = Dream.client ctx.req in 7 + let ip = Util.request_ip ctx.req in 8 8 let user_agent = Dream.header ctx.req "User-Agent" in 9 9 match req.grant_type with 10 10 | "authorization_code" -> (
+1 -1
pegasus/lib/api/server/createSession.ml
··· 25 25 in 26 26 let id = String.lowercase_ascii identifier in 27 27 (* apply rate limits after parsing body so we can create key from identifier *) 28 - let key = id ^ "-" ^ Dream.client req in 28 + let key = id ^ "-" ^ Util.request_ip req in 29 29 let _ = 30 30 Xrpc.consume_route_rate_limit ~name:"repo-write-hour" 31 31 ~duration_ms:Util.day ~max_points:300 ~key ~consume_points
+6
pegasus/lib/util.ml
··· 388 388 did_keys 389 389 <> None 390 390 391 + let request_ip req = 392 + Dream.header req "X-Forwarded-For" 393 + |> Option.value ~default:(Dream.client req) 394 + |> String.split_on_char ',' |> List.hd |> String.split_on_char ':' |> List.hd 395 + |> String.trim 396 + 391 397 let rec http_get ?(max_redirects = 5) ?headers uri = 392 398 let%lwt ans = Cohttp_lwt_unix.Client.get ?headers uri in 393 399 follow_redirect ~max_redirects uri ans
+1 -1
pegasus/lib/xrpc.ml
··· 18 18 ; calc_key: (context -> string option) option 19 19 ; calc_points: (context -> int) option } 20 20 21 - let default_calc_key (ctx : context) = Some (Dream.client ctx.req) 21 + let default_calc_key (ctx : context) = Some (Util.request_ip ctx.req) 22 22 23 23 let default_calc_points (_ctx : context) = 1 24 24