// An API that hands out tokens and checks them.
//
//   quillo run jwt.qwe      then open http://localhost:8080/token
//   curl -H "authorization: Bearer <token>" localhost:8080/me

use "jwt.qwer"

let SECRET = env("JWT_SECRET") ?? "change me: at least 32 random characters"

route GET /token = { token: jwt_sign({ sub: "user-7", role: "admin" }, SECRET, 3600)? }

route GET /me {
    let token = replace(request.headers.authorization ?? "", "Bearer ", "")
    let claims = jwt_verify(token, SECRET)
    if is_err(claims) { reply 401 { error: claims.error } }
    { user: claims.sub, role: claims.role }
}

// A token for another service, as an identity provider issues one: its audience and issuer
// checked, and one with no `exp` refused (it would be good for ever).
route GET /audience {
    let t = jwt_sign({ sub: "service:shop", aud: "orders", iss: "idp" }, SECRET, 60)?
    let forever = jwt_sign({ sub: "service:shop" }, SECRET, 0)?
    {
        orders: jwt_check(t, SECRET, { audience: "orders", issuer: "idp" })?.sub,
        not_billing: error(jwt_check(t, SECRET, { audience: "billing" })),
        no_exp: error(jwt_verify(forever, SECRET)),
        plain: jwt_verify(t, SECRET)?.aud,
    }
}

route GET /check {
    let t = jwt_sign({ sub: "user-7" }, SECRET, 60)?
    { verified: jwt_verify(t, SECRET)?.sub, wrong_secret: is_err(jwt_verify(t, "another secret")), peek: jwt_peek(t)?.sub }
}
