mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-08-26 13:24:48 +02:00
fix(auth-oauth1): use the signing key as the PLAINTEXT signature (#605)
This commit is contained in:
@@ -11,7 +11,8 @@
|
|||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "yaakcli build",
|
"build": "yaakcli build",
|
||||||
"dev": "yaakcli dev"
|
"dev": "yaakcli dev",
|
||||||
|
"test": "vp test --run tests"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"oauth-1.0a": "^2.2.6"
|
"oauth-1.0a": "^2.2.6"
|
||||||
|
|||||||
@@ -202,7 +202,10 @@ function hashFunction(signatureMethod: SigMethod) {
|
|||||||
return (base: string, privateKey: string) =>
|
return (base: string, privateKey: string) =>
|
||||||
crypto.createSign("RSA-SHA512").update(base).sign(privateKey, "base64");
|
crypto.createSign("RSA-SHA512").update(base).sign(privateKey, "base64");
|
||||||
case signatures.PLAINTEXT:
|
case signatures.PLAINTEXT:
|
||||||
return (base: string) => base;
|
// RFC 5849 3.4.4: the PLAINTEXT signature IS the signing key,
|
||||||
|
// `encoded(consumer secret)&encoded(token secret)`. Returning the base
|
||||||
|
// string put the whole percent-encoded request into oauth_signature.
|
||||||
|
return (_base: string, key: string) => key;
|
||||||
default:
|
default:
|
||||||
return (base: string, key: string) =>
|
return (base: string, key: string) =>
|
||||||
crypto.createHmac("sha1", key).update(base).digest("base64");
|
crypto.createHmac("sha1", key).update(base).digest("base64");
|
||||||
|
|||||||
@@ -0,0 +1,42 @@
|
|||||||
|
import { describe, expect, test } from "vite-plus/test";
|
||||||
|
import { plugin } from "../src";
|
||||||
|
|
||||||
|
function sign(values: Record<string, string>): string {
|
||||||
|
const result = plugin.authentication!.onApply!(
|
||||||
|
{} as never,
|
||||||
|
{
|
||||||
|
values,
|
||||||
|
method: "GET",
|
||||||
|
url: "https://api.example.com/resource",
|
||||||
|
} as never,
|
||||||
|
) as { setHeaders: { name: string; value: string }[] };
|
||||||
|
const header = result.setHeaders[0]!.value;
|
||||||
|
const match = header.match(/oauth_signature="([^"]*)"/);
|
||||||
|
return decodeURIComponent(match![1]!);
|
||||||
|
}
|
||||||
|
|
||||||
|
describe("PLAINTEXT signature", () => {
|
||||||
|
const base = {
|
||||||
|
signatureMethod: "PLAINTEXT",
|
||||||
|
consumerKey: "ck",
|
||||||
|
consumerSecret: "cs",
|
||||||
|
nonce: "abc123",
|
||||||
|
timestamp: "1700000000",
|
||||||
|
};
|
||||||
|
|
||||||
|
// RFC 5849 3.4.4: the PLAINTEXT signature is the signing key itself --
|
||||||
|
// encoded(consumer secret) "&" encoded(token secret) -- not the base string.
|
||||||
|
test("is the signing key, not the signature base string", () => {
|
||||||
|
expect(sign({ ...base, tokenKey: "tk", tokenSecret: "ts" })).toBe("cs&ts");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("keeps the trailing separator when there is no token secret", () => {
|
||||||
|
expect(sign(base)).toBe("cs&");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("percent-encodes reserved characters in the secrets", () => {
|
||||||
|
expect(sign({ ...base, consumerSecret: "c s", tokenKey: "tk", tokenSecret: "t&s" })).toBe(
|
||||||
|
"c%20s&t%26s",
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user