Skip to content

Commit 2719b6a

Browse files
Merge pull request #16 from solid/feat/eliminate-split
Replace split by more specific assumptions
2 parents 05713e9 + 959c176 commit 2719b6a

5 files changed

Lines changed: 38 additions & 6 deletions

File tree

src/algorithm/verifyDpopProofHttpUri.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ import { HttpUriVerificationError } from "../error";
1010
* @param htu The DPoP proof htu parameter
1111
*/
1212
export function verifyDpopProofHttpUri(uri: string, htu: string): void {
13-
const actual = uri.split("?")[0].split("#")[0];
14-
if (actual !== htu) {
15-
throw new HttpUriVerificationError(actual, htu);
13+
const rawUri = uri.replace(/[?#].*/, "");
14+
if (htu !== rawUri) {
15+
throw new HttpUriVerificationError(rawUri, htu);
1616
}
1717
}

src/algorithm/verifySolidAccessToken.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,11 @@ export async function verifySolidAccessToken(
3030
): Promise<SolidAccessTokenPayload> {
3131
// Extract access token value from authorization header
3232
const accessTokenValue = authorization.header.replace(/^(DPoP|Bearer) /, "");
33+
const accessTokenParts = accessTokenValue.split(".");
3334

3435
// Decode Solid access token payload
3536
const accessTokenPayload: unknown = decodeBase64UrlEncodedJson(
36-
accessTokenValue.split(".")[1]
37+
accessTokenParts[1]
3738
);
3839

3940
// Verify the Solid access token includes all required claims
@@ -82,7 +83,7 @@ export async function verifySolidAccessToken(
8283
const accessToken = {
8384
header: protectedHeader,
8485
payload,
85-
signature: accessTokenValue.split(".")[2],
86+
signature: accessTokenParts[2],
8687
};
8788

8889
isSolidAccessToken(accessToken);
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
export class HttpUriVerificationError extends Error {
22
constructor(actual: string, expected: string) {
33
super(
4-
`The DPoP proof htu parameter doesn't match the HTTP request URI without query and fragment parts.\nActual: ${actual}\nExpected: ${expected}`
4+
`The DPoP proof htu parameter must be the HTTP request URI without query and fragment parts.\nActual: ${actual}\nExpected: ${expected}`
55
);
66
}
77
}

test/algorithm/verifyDpopProof.test.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,23 @@ describe("verifyDpopProof()", () => {
123123
).resolves.not.toThrow();
124124
});
125125

126+
it("throws on invalid DPoP header", async () => {
127+
await expect(
128+
verifyDpopProof(
129+
"invalid",
130+
{
131+
payload: {
132+
cnf: { jkt: "0ZcOCORZNYy-DWpqq30jZyJGHTN0d2HglBV3uiguA4I" },
133+
},
134+
} as any as SolidAccessToken,
135+
"",
136+
"GET",
137+
"https://resource.example.org/protectedresource",
138+
() => false
139+
)
140+
).rejects.toThrow();
141+
});
142+
126143
it("throws on invalid ath claim", async () => {
127144
(jwtVerify as jest.Mock).mockResolvedValueOnce({
128145
payload: dpopPayloadWithAth,

test/algorithm/verifySolidAccessToken.test.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,20 @@ describe("verifySolidAccessToken()", () => {
7676
).toStrictEqual(bearerToken.payload);
7777
});
7878

79+
it("throws on invalid header", async () => {
80+
await expect(
81+
verifySolidAccessToken({
82+
header: "invalid",
83+
issuers: () =>
84+
Promise.resolve([
85+
"https://example.com/abc",
86+
"https://example.com/issuer",
87+
]),
88+
keySet: retrieveAccessTokenIssuerKeySet,
89+
})
90+
).rejects.toThrow();
91+
});
92+
7993
it("throws on non conforming access token", async () => {
8094
const wrongProtocolToken = {
8195
header: accessToken.header,

0 commit comments

Comments
 (0)