diff --git a/plugins/auth-oauth1/src/index.ts b/plugins/auth-oauth1/src/index.ts index e2f8c031..25e19b42 100644 --- a/plugins/auth-oauth1/src/index.ts +++ b/plugins/auth-oauth1/src/index.ts @@ -161,7 +161,7 @@ export const plugin: PluginDefinition = { if (values.timestamp) requestData.data.oauth_timestamp = String(values.timestamp); if (values.verifier) requestData.data.oauth_verifier = String(values.verifier); - let token: OAuth.Token | { key: string } | undefined; + let token: OAuth.Token | { key: string } | { secret: string } | undefined; if (pkSigs.includes(signatureMethod)) { token = { @@ -172,6 +172,10 @@ export const plugin: PluginDefinition = { token = { key: String(values.tokenKey), secret: String(values.tokenSecret) }; } else if (values.tokenKey) { token = { key: String(values.tokenKey) }; + } else if (values.tokenSecret) { + // The secret still joins the signing key without an access token; + // leaving `key` out keeps oauth_token out of the header entirely + token = { secret: String(values.tokenSecret) }; } const authParams = oauth.authorize(requestData, token as OAuth.Token | undefined); diff --git a/plugins/auth-oauth1/tests/plaintext.test.ts b/plugins/auth-oauth1/tests/plaintext.test.ts index f2517f60..e82aacbc 100644 --- a/plugins/auth-oauth1/tests/plaintext.test.ts +++ b/plugins/auth-oauth1/tests/plaintext.test.ts @@ -34,6 +34,21 @@ describe("PLAINTEXT signature", () => { expect(sign(base)).toBe("cs&"); }); + test("includes the token secret without an access token, omitting oauth_token", () => { + const result = plugin.authentication!.onApply!( + {} as never, + { + values: { ...base, tokenSecret: "ts" }, + 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="([^"]*)"/); + expect(decodeURIComponent(match![1]!)).toBe("cs&ts"); + expect(header).not.toContain("oauth_token="); + }); + test("percent-encodes reserved characters in the secrets", () => { expect(sign({ ...base, consumerSecret: "c s", tokenKey: "tk", tokenSecret: "t&s" })).toBe( "c%20s&t%26s",