Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions packages/core/src/api/refreshUserInfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,19 +91,19 @@ export const refreshUserInfo = async <DefaultUser extends User = User>(
identity: ctx.identity,
})
return {
success: true,
success: !!session,
headers: mergedHeaders,
session,
session: session,
toResponse: () => {
return Response.json(
{
success: !!session,
session,
success: true,
},
{ headers: mergedHeaders, status: 200 }
)
},
}
} as RefreshUserInfoAPIReturn<DefaultUser>
Comment thread
halvaradop marked this conversation as resolved.
} catch (error) {
const { code, message, statusCode } = handleApiError(
error,
Expand Down
7 changes: 5 additions & 2 deletions packages/core/src/shared/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -231,10 +231,13 @@ export const getStandardSession = async ({
}) => {
const claims = await jwt.verifyToken(sessionToken)
const parsedClaims = identity.skipValidation ? claims : await identity.schemaRegistry.parseWithJWT(claims)
const { exp: _exp, iat: _iat, mexp: _mexp, ...defaultPayload } = parsedClaims
const { exp, iat: _iat, mexp: _mexp, ...defaultPayload } = parsedClaims
const userClaims = await identity.schemaRegistry.parse(defaultPayload)
if (!userClaims.sub) return null
return userClaims
return {
user: userClaims,
expires: exp,
}
}

export const transformToTokenPayload = (tokens: OAuthAccessTokenResponseType & { id_token?: string }) => {
Expand Down
76 changes: 37 additions & 39 deletions packages/core/test/actions/providers/user/stateless.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,10 +90,8 @@ describe("refreshUserInfo action", () => {
ok: true,
headers: new Headers({ "Content-Type": "application/json" }),
json: async () => ({
id: "1234567890",
email: "john@example.com",
name: "John Doe",
image: "https://example.com/image.jpg",
...sessionPayload,
email: "john.updated@example.com",
}),
})
vi.stubGlobal("fetch", mockFetch)
Expand All @@ -111,10 +109,11 @@ describe("refreshUserInfo action", () => {
expect(await response.json()).toEqual({
success: true,
session: {
sub: "1234567890",
email: "john@example.com",
name: "John Doe",
image: "https://example.com/image.jpg",
user: {
...sessionPayload,
email: "john.updated@example.com",
},
expires: expect.any(Number),
},
})
expect(response.status).toBe(200)
Expand Down Expand Up @@ -294,9 +293,8 @@ describe("refreshUserInfo action", () => {
headers: new Headers({ "Content-Type": "application/json" }),
json: async () => ({
id: "1234567890",
email: "john@example.com",
name: "John Doe",
image: "https://example.com/image.jpg",
...sessionPayload,
email: "john.updated@example.com",
}),
})
vi.stubGlobal("fetch", mockFetch)
Expand All @@ -314,10 +312,11 @@ describe("refreshUserInfo action", () => {
expect(await response.json()).toEqual({
success: true,
session: {
sub: "1234567890",
email: "john@example.com",
name: "John Doe",
image: "https://example.com/image.jpg",
user: {
...sessionPayload,
email: "john.updated@example.com",
},
expires: expect.any(Number),
},
})
expect(mockFetch).toHaveBeenCalledTimes(2)
Expand Down Expand Up @@ -388,10 +387,9 @@ describe("refreshUserInfo action", () => {
ok: true,
headers: new Headers({ "Content-Type": "application/json" }),
json: async () => ({
...sessionPayload,
id: "1234567890",
email: "john@example.com",
name: "John Doe",
image: "https://example.com/image.jpg",
email: "john.updated@example.com",
}),
})
vi.stubGlobal("fetch", mockFetch)
Expand All @@ -409,10 +407,11 @@ describe("refreshUserInfo action", () => {
expect(await response.json()).toEqual({
success: true,
session: {
sub: "1234567890",
email: "john@example.com",
name: "John Doe",
image: "https://example.com/image.jpg",
user: {
...sessionPayload,
email: "john.updated@example.com",
},
expires: expect.any(Number),
},
})
expect(response.headers.get("set-cookie")).toContain("aura-auth.session_token=")
Expand Down Expand Up @@ -449,10 +448,9 @@ describe("refreshUserInfo action", () => {
ok: true,
headers: new Headers({ "Content-Type": "application/json" }),
json: async () => ({
...sessionPayload,
id: "1234567890",
email: "john@example.com",
name: "John Doe",
image: "https://example.com/image.jpg",
email: "john.updated@example.com",
nickname: "johnny",
email_verified: true,
}),
Expand All @@ -471,12 +469,13 @@ describe("refreshUserInfo action", () => {

expect(await response.json()).toEqual({
success: true,
session: expect.objectContaining({
sub: "1234567890",
email: "john@example.com",
name: "John Doe",
image: "https://example.com/image.jpg",
}),
session: {
user: {
...sessionPayload,
email: "john.updated@example.com",
},
expires: expect.any(Number),
},
})
})

Expand All @@ -491,10 +490,8 @@ describe("refreshUserInfo action", () => {
ok: true,
headers: new Headers({ "Content-Type": "application/json" }),
json: async () => ({
id: "1234567890",
email: "john@example.com",
name: "John Doe",
image: "https://example.com/image.jpg",
...sessionPayload,
email: "john.updated@example.com",
}),
})
vi.stubGlobal("fetch", mockFetch)
Expand All @@ -512,10 +509,11 @@ describe("refreshUserInfo action", () => {
expect(await response.json()).toEqual({
success: true,
session: {
sub: "1234567890",
email: "john@example.com",
name: "John Doe",
image: "https://example.com/image.jpg",
user: {
...sessionPayload,
email: "john.updated@example.com",
},
expires: expect.any(Number),
},
})
})
Expand Down
114 changes: 54 additions & 60 deletions packages/core/test/api/stateless/getSession.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { getCookie, getSetCookie } from "@/cookie.ts"
import { createAuth } from "@/createAuth.ts"
import { api, jose } from "@test/presets.ts"
import { describe, test, expect } from "vitest"
import { createAuth } from "@/createAuth.ts"
import { getCookie, getSetCookie } from "@/cookie.ts"
import { api, jose, sessionPayload } from "@test/presets.ts"

describe("getSession", () => {
test("getSession with no session token", async () => {
Expand All @@ -25,95 +25,91 @@ describe("getSession", () => {
})

test("getSession with valid session token", async () => {
const jwt = await jose.encodeJWT({
sub: "123",
name: "Alice",
email: "alice@example.com",
})
const jwt = await jose.encodeJWT(sessionPayload)
const session = await api.getSession({
headers: { Cookie: `aura-auth.session_token=${jwt}` },
})
expect(session.session).toMatchObject({
user: {
sub: "123",
name: "Alice",
email: "alice@example.com",
expect(session).toEqual({
success: true,
session: {
user: sessionPayload,
expires: expect.any(String),
},
expires: expect.any(String),
headers: expect.any(Headers),
toResponse: expect.any(Function),
})
})

test("getSession with expired session token", async () => {
const jwt = await jose.encodeJWT({
sub: "123",
name: "Alice",
email: "",
...sessionPayload,
exp: Math.floor(Date.now() / 1000) - 60,
})
const session = await api.getSession({
headers: { Cookie: `aura-auth.session_token=${jwt}` },
})
expect(session).toMatchObject({
expect(session).toEqual({
session: null,
headers: {},
success: false,
error: {
code: "GET_SESSION_FAILED",
message: "Failed to retrieve session. The session token may be missing, expired, or invalid.",
},
headers: expect.any(Headers),
toResponse: expect.any(Function),
})
expect(getSetCookie(session.headers, "aura-auth.session_token")).toBe("")
})

test("getSession with session token missing sub claim", async () => {
const jwt = await jose.encodeJWT({
name: "Alice",
email: "alice@example.com",
})
const { sub: _, ...spreadSession } = sessionPayload
const jwt = await jose.encodeJWT(spreadSession)
const session = await api.getSession({
headers: { Cookie: `aura-auth.session_token=${jwt}` },
})
expect(session).toMatchObject({
expect(session).toEqual({
session: null,
headers: {},
success: false,
error: {
code: "GET_SESSION_FAILED",
message: "Failed to retrieve session. The session token may be missing, expired, or invalid.",
},
headers: expect.any(Headers),
toResponse: expect.any(Function),
})
})

test("getSession with extra claims in session token", async () => {
const jwt = await jose.encodeJWT({
sub: "123",
name: "Alice",
email: "alice@example.com",
...sessionPayload,
role: "admin",
permissions: ["read", "write"],
})
const session = await api.getSession({
headers: { Cookie: `aura-auth.session_token=${jwt}` },
})
expect(session.session).toMatchObject({
user: {
sub: "123",
name: "Alice",
email: "alice@example.com",
expect(session).toEqual({
success: true,
session: {
user: sessionPayload,
expires: expect.any(String),
},
expires: expect.any(String),
headers: expect.any(Headers),
toResponse: expect.any(Function),
})
expect(session.session?.user).not.toHaveProperty("role")
expect(session.session?.user).not.toHaveProperty("permissions")
const decodeSession = await jose.decodeJWT(getCookie(session.headers, "aura-auth.session_token")!)
expect(decodeSession).toMatchObject({
sub: "123",
name: "Alice",
email: "alice@example.com",
expect(session.session).not.toContainEqual({
role: "admin",
permissions: ["read", "write"],
})
expect(session.session?.user).not.toHaveProperty("role")
expect(session.session?.user).not.toHaveProperty("permissions")
const decodeSession = await jose.decodeJWT(getCookie(session.headers, "aura-auth.session_token")!)
expect(decodeSession).toMatchObject(sessionPayload)
Comment thread
halvaradop marked this conversation as resolved.
})

test("getSession refreshes session token if exp is close", async () => {
const auth = createAuth({ oauth: [], session: { jwt: { expirationStrategy: "rolling" } } })

const jwt = await auth.jose.encodeJWT({
sub: "123",
name: "Alice",
email: "alice@example.com",
...sessionPayload,
iat: Math.floor(Date.now() / 1000) - 3600,
exp: Math.floor(Date.now() / 1000) + 10,
role: "admin",
Expand All @@ -122,23 +118,21 @@ describe("getSession", () => {
const session = await auth.api.getSession({
headers: { Cookie: `aura-auth.session_token=${jwt}` },
})
expect(session.session).toMatchObject({
user: {
sub: "123",
name: "Alice",
email: "alice@example.com",
expect(session).toEqual({
success: true,
session: {
user: sessionPayload,
expires: expect.any(String),
},
headers: expect.any(Headers),
toResponse: expect.any(Function),
})
expect(session.session).not.toContainEqual({
role: "admin",
permissions: ["read", "write"],
})
expect(session.session?.user).not.toHaveProperty("role")
expect(session.session?.user).not.toHaveProperty("permissions")

const decodeSession = await jose.decodeJWT(getSetCookie(session.headers, "aura-auth.session_token")!)
expect(decodeSession).toMatchObject({
sub: "123",
name: "Alice",
email: "alice@example.com",
})
expect(session.session?.user).not.toHaveProperty("role")
expect(session.session?.user).not.toHaveProperty("permissions")
expect(decodeSession).toMatchObject(sessionPayload)
})
})
Loading
Loading