Skip to content

Commit

Permalink
Add refresh token (#44)
Browse files Browse the repository at this point in the history
* feat: extract refresh function

* Version Packages (#43)

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>

* refresh token tweaks

---------

Co-authored-by: Timo Strackfeldt <[email protected]>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
  • Loading branch information
4 people authored Dec 12, 2024
1 parent 7cc82d2 commit 64fd022
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 31 deletions.
17 changes: 7 additions & 10 deletions examples/client/cloudflare-api/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ export default {
},
)
const resp = Response.json(verified.subject)
setSession(resp, verified.access, verified.refresh)
if (verified.tokens)
setSession(resp, verified.tokens.access, verified.tokens.refresh)
return resp
} catch (e) {
console.error(e)
Expand All @@ -58,21 +59,17 @@ export default {
},
}

function setSession(
response: Response,
accessToken?: string,
refreshToken?: string,
) {
if (accessToken) {
function setSession(response: Response, access: string, refresh: string) {
if (access) {
response.headers.append(
"Set-Cookie",
`access_token=${accessToken}; HttpOnly; SameSite=Strict; Path=/; Max-Age=2147483647`,
`access_token=${access}; HttpOnly; SameSite=Strict; Path=/; Max-Age=2147483647`,
)
}
if (refreshToken) {
if (refresh) {
response.headers.append(
"Set-Cookie",
`refresh_token=${refreshToken}; HttpOnly; SameSite=Strict; Path=/; Max-Age=2147483647`,
`refresh_token=${refresh}; HttpOnly; SameSite=Strict; Path=/; Max-Age=2147483647`,
)
}
}
68 changes: 47 additions & 21 deletions packages/openauth/src/client.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
import { createLocalJWKSet, errors, JSONWebKeySet, jwtVerify } from "jose"
import {
createLocalJWKSet,
errors,
JSONWebKeySet,
jwtVerify,
decodeJwt,
} from "jose"
import { SubjectSchema } from "./session.js"
import type { v1 } from "@standard-schema/spec"
import {
Expand Down Expand Up @@ -109,6 +115,39 @@ export function createClient(input: {
refresh: json.refresh_token as string,
}
},
async refresh(
refresh: string,
opts?: {
access?: string
},
) {
if (!opts?.access) {
const decoded = decodeJwt(refresh)
// allow 30s window for expiration
if (decoded.exp < Date.now() / 1000 + 30) {
return
}
}
const tokens = await f(issuer + "/token", {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
body: new URLSearchParams({
grant_type: "refresh_token",
refresh_token: refresh,
}).toString(),
})
const json = (await tokens.json()) as any
if (!tokens.ok) {
console.error(json)
throw new InvalidRefreshTokenError()
}
return {
access: json.access_token as string,
refresh: json.refresh_token as string,
}
},
async verify<T extends SubjectSchema>(
subjects: T,
token: string,
Expand Down Expand Up @@ -151,30 +190,17 @@ export function createClient(input: {
}
} catch (e) {
if (e instanceof errors.JWTExpired && options?.refresh) {
const wk = await getIssuer()
const tokens = await f(wk.token_endpoint, {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
body: new URLSearchParams({
grant_type: "refresh_token",
refresh_token: options.refresh,
}).toString(),
})
const json = (await tokens.json()) as any
if (!tokens.ok) {
console.error(json)
throw new InvalidRefreshTokenError()
}
const verified = await result.verify(subjects, json.access_token, {
refresh: json.refresh_token,
const tokens = await this.refresh(options.refresh)

const verified = await result.verify(subjects, tokens.access, {
refresh: tokens.refresh,
issuer,
fetch: options?.fetch,
})

verified.tokens = {
access: json.access_token,
refresh: json.refresh_token,
access: tokens.access,
refresh: tokens.refresh,
}
return verified
}
Expand Down

0 comments on commit 64fd022

Please sign in to comment.