Skip to content
LogoLogo

@portable/oauth1

Functions

OAuth1.authorization

Signs a request and returns the value for its Authorization header. The request is not changed: a form body is read from a clone. Use it with HTTP clients that don't take a Request.

async function authorization(
  request: Request,
  options: authorization.Options,
): Promise<string>;
OptionTypeDefaultDescription
signatureMethod"HMAC-SHA1" | "HMAC-SHA256" | "PLAINTEXT" | "RSA-SHA1"'HMAC-SHA1'
consumer{ key: string; secret: string; } | { key: string; privateKey: CryptoKey | string; }privateKey is an RSASSA-PKCS1-v1_5 CryptoKey with SHA-1, or a PEM PRIVATE KEY (PKCS #8) or RSA PRIVATE KEY (PKCS #1) block. A PEM string is imported on every call.
hmacanyWebCrypto.hmacComputes the HMAC for HMAC-SHA1 and HMAC-SHA256. @noble/hashes is sync and several times faster on Node.
digestanyWebCrypto.digestHashes the body for oauth_body_hash.
tokenTokenOmit it to sign with client credentials only, as when requesting temporary credentials.
realmstringSent as the realm header parameter. It is not signed.
callbackstringSent as oauth_callback when requesting temporary credentials.
verifierstringSent as oauth_verifier when exchanging temporary credentials for an access token.
bodyHashbooleanfalseAdd oauth_body_hash, the base64 SHA-1 (SHA-256 for HMAC-SHA256) of the request body, as the OAuth Request Body Hash extension and LTI require. Form bodies never get one, because their parameters are signed already.
signalAbortSignalRejects with signal.reason when aborted.
noncestring32 random hex digitsoauth_nonce. Set it only in tests.
nowanynew Date()The time sent as oauth_timestamp, in whole seconds, as a Date or a Temporal.Instant. Set it only in tests.

Throws

  • UnsupportedError For an unknown signatureMethod.
  • RangeError For an RSA private key that can't be used, or an invalid now.
import * as OAuth1 from '@portable/oauth1';
 
const header = await OAuth1.authorization(
  new Request('https://api.example.com/items'),
  {
    consumer: { key: 'dpf43f3p2l4k3l03', secret: 'kd94hf93k423kf44' },
    token: { key: 'nnch734d00sl2jdk', secret: 'pfkkdhi9sl3r4s00' },
  },
);
// 'OAuth oauth_consumer_key="dpf43f3p2l4k3l03", oauth_nonce="…", oauth_signature="…", …'

OAuth1.sign

Signs a request and returns a new Request with the signature in its Authorization header, or in its URL with placement: 'query'. Like new Request(request), it uses up the body of the original request.

async function sign(
  request: Request,
  options: sign.Options,
): Promise<Request>;
OptionTypeDefaultDescription
signatureMethod"HMAC-SHA1" | "HMAC-SHA256" | "PLAINTEXT" | "RSA-SHA1"'HMAC-SHA1'
consumer{ key: string; secret: string; } | { key: string; privateKey: CryptoKey | string; }privateKey is an RSASSA-PKCS1-v1_5 CryptoKey with SHA-1, or a PEM PRIVATE KEY (PKCS #8) or RSA PRIVATE KEY (PKCS #1) block. A PEM string is imported on every call.
hmacanyWebCrypto.hmacComputes the HMAC for HMAC-SHA1 and HMAC-SHA256. @noble/hashes is sync and several times faster on Node.
digestanyWebCrypto.digestHashes the body for oauth_body_hash.
tokenTokenOmit it to sign with client credentials only, as when requesting temporary credentials.
realmstringSent as the realm header parameter. It is not signed.
callbackstringSent as oauth_callback when requesting temporary credentials.
verifierstringSent as oauth_verifier when exchanging temporary credentials for an access token.
bodyHashbooleanfalseAdd oauth_body_hash, the base64 SHA-1 (SHA-256 for HMAC-SHA256) of the request body, as the OAuth Request Body Hash extension and LTI require. Form bodies never get one, because their parameters are signed already.
signalAbortSignalRejects with signal.reason when aborted.
noncestring32 random hex digitsoauth_nonce. Set it only in tests.
nowanynew Date()The time sent as oauth_timestamp, in whole seconds, as a Date or a Temporal.Instant. Set it only in tests.
placement"header" | "query"'header'Where the protocol parameters go: the Authorization header, or the URL query.

Throws

  • UnsupportedError For an unknown signatureMethod.
  • RangeError For an RSA private key that can't be used, or an invalid now.
import * as OAuth1 from '@portable/oauth1';
 
const request = new Request('https://api.example.com/statuses', {
  method: 'POST',
  body: new URLSearchParams({ status: 'Hello' }),
});
const response = await fetch(
  await OAuth1.sign(request, {
    consumer: { key: 'dpf43f3p2l4k3l03', secret: 'kd94hf93k423kf44' },
    token: { key: 'nnch734d00sl2jdk', secret: 'pfkkdhi9sl3r4s00' },
  }),
);

Errors

OAuth1.UnsupportedError

Thrown for a signatureMethod other than 'HMAC-SHA1', 'HMAC-SHA256', 'RSA-SHA1' and 'PLAINTEXT'.

class UnsupportedError extends Errors.UnsupportedError {
  readonly kind: string;
}
import * as OAuth1 from '@portable/oauth1';
 
try {
  await OAuth1.authorization(request, {
    signatureMethod: 'RSA-SHA256' as never,
    consumer,
  });
} catch (error) {
  if (error instanceof OAuth1.UnsupportedError) {
    console.log(error.message);
  }
}

Types

OAuth1.Credentials

The client credentials and how to sign with them. HMAC and PLAINTEXT use the shared secret. RSA-SHA1 uses the client's RSA private key, as a CryptoKey or a PEM string.

type Credentials = {
    signatureMethod?:  |  |  | undefined;
    consumer: {
        key: string;
        secret: string;
    };
} | {
    signatureMethod: ;
    consumer: {
        key: string;
        privateKey: CryptoKey | string;
    };
};

OAuth1.SignatureMethod

The oauth_signature_method values this package signs with.

type SignatureMethod =  |  |  | ;

OAuth1.Token

Token credentials, or the temporary credentials while exchanging them for an access token.

type Token = {
  key: string;
  secret?: string | undefined;
};