@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>;| Option | Type | Default | Description |
|---|---|---|---|
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. | |
hmac | any | WebCrypto.hmac | Computes the HMAC for HMAC-SHA1 and HMAC-SHA256. @noble/hashes is sync and several times faster on Node. |
digest | any | WebCrypto.digest | Hashes the body for oauth_body_hash. |
token | Token | Omit it to sign with client credentials only, as when requesting temporary credentials. | |
realm | string | Sent as the realm header parameter. It is not signed. | |
callback | string | Sent as oauth_callback when requesting temporary credentials. | |
verifier | string | Sent as oauth_verifier when exchanging temporary credentials for an access token. | |
bodyHash | boolean | false | Add 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. |
signal | AbortSignal | Rejects with signal.reason when aborted. | |
nonce | string | 32 random hex digits | oauth_nonce. Set it only in tests. |
now | any | new Date() | The time sent as oauth_timestamp, in whole seconds, as a Date or a Temporal.Instant. Set it only in tests. |
Throws
UnsupportedErrorFor an unknownsignatureMethod.RangeErrorFor an RSA private key that can't be used, or an invalidnow.
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>;| Option | Type | Default | Description |
|---|---|---|---|
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. | |
hmac | any | WebCrypto.hmac | Computes the HMAC for HMAC-SHA1 and HMAC-SHA256. @noble/hashes is sync and several times faster on Node. |
digest | any | WebCrypto.digest | Hashes the body for oauth_body_hash. |
token | Token | Omit it to sign with client credentials only, as when requesting temporary credentials. | |
realm | string | Sent as the realm header parameter. It is not signed. | |
callback | string | Sent as oauth_callback when requesting temporary credentials. | |
verifier | string | Sent as oauth_verifier when exchanging temporary credentials for an access token. | |
bodyHash | boolean | false | Add 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. |
signal | AbortSignal | Rejects with signal.reason when aborted. | |
nonce | string | 32 random hex digits | oauth_nonce. Set it only in tests. |
now | any | new 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
UnsupportedErrorFor an unknownsignatureMethod.RangeErrorFor an RSA private key that can't be used, or an invalidnow.
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;
};