or run

tessl search
Log in

Version

Files

tile.json

task.mdevals/scenario-1/

OAuth Client Implementation

Summary

Implement an OAuth 1.0a client that performs a complete three-legged authentication flow to authorize with a service provider and make authenticated API requests.

Description

Your task is to build an OAuth 1.0a client implementation that handles all three phases of the OAuth authentication flow: obtaining a request token, exchanging it for an access token after user authorization, and making authenticated API calls.

The client should:

  1. Request Token Phase: Generate a signed request to obtain a temporary request token from the provider, including a callback URL
  2. User Authorization Phase: Construct an authorization URL where the user would be redirected (no actual HTTP calls needed for this phase)
  3. Access Token Exchange: After receiving the verifier from user authorization, exchange the request token for permanent access credentials
  4. Authenticated Requests: Make signed API requests using the access token to access protected resources

All requests must be properly signed according to OAuth 1.0a specifications. Use HMAC-SHA1 as the signature method.

Requirements

Implement the following in oauth-client.js:

Function 1: getRequestToken(consumerKey, consumerSecret, callbackUrl, requestTokenUrl)

Generates signature data for requesting a temporary token.

Parameters:

  • consumerKey (string): Your application's consumer key
  • consumerSecret (string): Your application's consumer secret
  • callbackUrl (string): The URL where the provider will redirect after authorization
  • requestTokenUrl (string): The provider's request token endpoint URL

Returns: An object containing:

  • signature (string): The OAuth signature for the request
  • oauthParams (object): All OAuth parameters including signature

Function 2: buildAuthorizationUrl(authorizeUrl, requestToken)

Constructs the URL where users should be directed to authorize your application.

Parameters:

  • authorizeUrl (string): The provider's authorization endpoint URL
  • requestToken (string): The request token obtained from the first step

Returns: The complete authorization URL as a string

Function 3: getAccessToken(consumerKey, consumerSecret, requestToken, requestTokenSecret, verifier, accessTokenUrl)

Generates signature data for exchanging the request token for an access token.

Parameters:

  • consumerKey (string): Your application's consumer key
  • consumerSecret (string): Your application's consumer secret
  • requestToken (string): The request token from step 1
  • requestTokenSecret (string): The token secret received with the request token
  • verifier (string): The verification code received after user authorization
  • accessTokenUrl (string): The provider's access token endpoint URL

Returns: An object containing:

  • signature (string): The OAuth signature for the request
  • oauthParams (object): All OAuth parameters including signature and verifier

Function 4: makeAuthenticatedRequest(httpMethod, apiUrl, consumerKey, consumerSecret, accessToken, accessTokenSecret, additionalParams)

Generates signature data for making authenticated API requests.

Parameters:

  • httpMethod (string): HTTP method (e.g., 'GET', 'POST')
  • apiUrl (string): The API endpoint URL
  • consumerKey (string): Your application's consumer key
  • consumerSecret (string): Your application's consumer secret
  • accessToken (string): The access token from step 3
  • accessTokenSecret (string): The token secret received with the access token
  • additionalParams (object): Additional request parameters (query or body parameters)

Returns: An object containing:

  • signature (string): The OAuth signature for the request
  • oauthParams (object): All OAuth parameters including signature

Implementation Notes

  • Use HMAC-SHA1 as the signature method for all requests
  • Include standard OAuth parameters: oauth_consumer_key, oauth_signature_method, oauth_timestamp, oauth_nonce, oauth_version, oauth_signature
  • For request token: include oauth_callback
  • For access token: include oauth_token and oauth_verifier
  • For authenticated requests: include oauth_token
  • Generate unique oauth_nonce values (can use random strings or UUIDs)
  • Use current Unix timestamp for oauth_timestamp
  • Set oauth_version to "1.0"

Dependencies { .dependencies }

oauth-sign { .dependency }

Provides OAuth 1.0 signature generation support.

Test Cases

Write tests in oauth-client.test.js to verify your implementation.

Test 1: Request Token Signature Generation @test

Verify that the request token phase generates valid signatures.

Test Code:

const { getRequestToken } = require('./oauth-client');

const result = getRequestToken(
  'consumer-key-123',
  'consumer-secret-456',
  'http://example.com/callback',
  'https://api.provider.com/oauth/request_token'
);

// Should return an object with signature and oauthParams
console.assert(typeof result.signature === 'string', 'Signature should be a string');
console.assert(result.signature.length > 0, 'Signature should not be empty');
console.assert(result.oauthParams.oauth_consumer_key === 'consumer-key-123', 'Should include consumer key');
console.assert(result.oauthParams.oauth_callback === 'http://example.com/callback', 'Should include callback URL');
console.assert(result.oauthParams.oauth_signature_method === 'HMAC-SHA1', 'Should use HMAC-SHA1');

Test 2: Authorization URL Construction @test

Verify that the authorization URL is correctly formatted.

Test Code:

const { buildAuthorizationUrl } = require('./oauth-client');

const url = buildAuthorizationUrl(
  'https://api.provider.com/oauth/authorize',
  'request-token-xyz'
);

// Should return a properly formatted URL
console.assert(url.includes('https://api.provider.com/oauth/authorize'), 'Should contain base URL');
console.assert(url.includes('request-token-xyz'), 'Should contain request token');
console.log('Authorization URL:', url);

Test 3: Access Token Signature Generation @test

Verify that the access token exchange generates valid signatures with both consumer and token secrets.

Test Code:

const { getAccessToken } = require('./oauth-client');

const result = getAccessToken(
  'consumer-key-123',
  'consumer-secret-456',
  'request-token-xyz',
  'request-secret-789',
  'verifier-code-abc',
  'https://api.provider.com/oauth/access_token'
);

// Should return an object with signature and oauthParams
console.assert(typeof result.signature === 'string', 'Signature should be a string');
console.assert(result.oauthParams.oauth_token === 'request-token-xyz', 'Should include request token');
console.assert(result.oauthParams.oauth_verifier === 'verifier-code-abc', 'Should include verifier');

Test 4: Authenticated API Request Signature @test

Verify that authenticated requests include all necessary parameters.

Test Code:

const { makeAuthenticatedRequest } = require('./oauth-client');

const result = makeAuthenticatedRequest(
  'POST',
  'https://api.provider.com/1.1/statuses/update.json',
  'consumer-key-123',
  'consumer-secret-456',
  'access-token-final',
  'access-secret-final',
  { status: 'Hello World' }
);

// Should return an object with signature and oauthParams
console.assert(typeof result.signature === 'string', 'Signature should be a string');
console.assert(result.oauthParams.oauth_token === 'access-token-final', 'Should include access token');
console.assert(result.oauthParams.oauth_signature_method === 'HMAC-SHA1', 'Should use HMAC-SHA1');