//// Per-user Discogs credentials (durable OAuth 1.0a access token + username), //// keyed by the user's DID through a generic `sessions.Store` backend. import crate_server/discogs_oauth.{type TokenPair, TokenPair} import crate_server/oauth/sessions.{type Store} import gleam/dynamic/decode import gleam/json import gleam/option.{type Option} import gleam/result pub type Creds { Creds(access: TokenPair, username: String) } pub fn save(store: Store, did: String, creds: Creds) -> Result(Nil, String) { store.save(did, encode(creds)) } pub fn fetch(store: Store, did: String) -> Option(Creds) { store.fetch(did) |> option.then(fn(raw) { option.from_result(decode_creds(raw)) }) } pub fn remove(store: Store, did: String) -> Nil { store.remove(did) } fn encode(c: Creds) -> String { json.object([ #("token", json.string(c.access.token)), #("secret", json.string(c.access.secret)), #("username", json.string(c.username)), ]) |> json.to_string } fn decode_creds(raw: String) -> Result(Creds, Nil) { let decoder = { use token <- decode.field("token", decode.string) use secret <- decode.field("secret", decode.string) use username <- decode.field("username", decode.string) decode.success(Creds(access: TokenPair(token:, secret:), username:)) } json.parse(raw, decoder) |> result.replace_error(Nil) }