diff --git a/packages/grpc-js-core/src/call-credentials.ts b/packages/grpc-js-core/src/call-credentials.ts index f0ad0980..888e4c62 100644 --- a/packages/grpc-js-core/src/call-credentials.ts +++ b/packages/grpc-js-core/src/call-credentials.ts @@ -2,33 +2,35 @@ import {map, reduce} from 'lodash'; import {Metadata} from './metadata'; -export type CallMetadataGenerator = - (options: T, cb: (err: Error|null, metadata?: Metadata) => void) => +export type CallMetadataOptions = { service_url?: string; }; + +export type CallMetadataGenerator = + (options: CallMetadataOptions, cb: (err: Error|null, metadata?: Metadata) => void) => void; /** * A class that represents a generic method of adding authentication-related * metadata on a per-request basis. */ -export interface CallCredentials { +export interface CallCredentials { /** * Asynchronously generates a new Metadata object. * @param options Options used in generating the Metadata object. */ - generateMetadata(options: T): Promise; + generateMetadata(options: CallMetadataOptions): Promise; /** * Creates a new CallCredentials object from properties of both this and * another CallCredentials object. This object's metadata generator will be * called first. * @param callCredentials The other CallCredentials object. */ - compose(callCredentials: CallCredentials): CallCredentials; + compose(callCredentials: CallCredentials): CallCredentials; } -class ComposedCallCredentials implements CallCredentials { - constructor(private creds: CallCredentials[]) {} +class ComposedCallCredentials implements CallCredentials { + constructor(private creds: CallCredentials[]) {} - async generateMetadata(options: T): Promise { + async generateMetadata(options: CallMetadataOptions): Promise { let base: Metadata = new Metadata(); let generated: Metadata[] = await Promise.all( map(this.creds, (cred) => cred.generateMetadata(options))); @@ -38,15 +40,15 @@ class ComposedCallCredentials implements CallCredentials { return base; } - compose(other: CallCredentials): CallCredentials { - return new ComposedCallCredentials([...this.creds, other]); + compose(other: CallCredentials): CallCredentials { + return new ComposedCallCredentials(this.creds.concat([other])); } } -class SingleCallCredentials implements CallCredentials { - constructor(private metadataGenerator: CallMetadataGenerator) {} +class SingleCallCredentials implements CallCredentials { + constructor(private metadataGenerator: CallMetadataGenerator) {} - generateMetadata(options: T): Promise { + generateMetadata(options: CallMetadataOptions): Promise { return new Promise((resolve, reject) => { this.metadataGenerator(options, (err, metadata) => { if (metadata !== undefined) { @@ -58,17 +60,17 @@ class SingleCallCredentials implements CallCredentials { }); } - compose(other: CallCredentials): CallCredentials { - return new ComposedCallCredentials([this, other]); + compose(other: CallCredentials): CallCredentials { + return new ComposedCallCredentials([this, other]); } } -class EmptyCallCredentials implements CallCredentials<{}> { - generateMetadata(options: {}): Promise { +class EmptyCallCredentials implements CallCredentials { + generateMetadata(options: CallMetadataOptions): Promise { return Promise.resolve(new Metadata()); } - compose(other: CallCredentials): CallCredentials { + compose(other: CallCredentials): CallCredentials { return other; } } @@ -81,12 +83,12 @@ export namespace CallCredentials { * generates a Metadata object based on these options, which is passed back * to the caller via a supplied (err, metadata) callback. */ - export function createFromMetadataGenerator( - metadataGenerator: CallMetadataGenerator): CallCredentials { + export function createFromMetadataGenerator( + metadataGenerator: CallMetadataGenerator): CallCredentials { return new SingleCallCredentials(metadataGenerator); } - export function createEmpty(): CallCredentials<{}> { + export function createEmpty(): CallCredentials { return new EmptyCallCredentials(); } } diff --git a/packages/grpc-js-core/src/channel-credentials.ts b/packages/grpc-js-core/src/channel-credentials.ts index 98986ff4..419e3d17 100644 --- a/packages/grpc-js-core/src/channel-credentials.ts +++ b/packages/grpc-js-core/src/channel-credentials.ts @@ -7,19 +7,19 @@ import {CallCredentials} from './call-credentials'; * as a set of per-call credentials, which are applied to every method call made * over a channel initialized with an instance of this class. */ -export interface ChannelCredentials { +export interface ChannelCredentials { /** * Returns a copy of this object with the included set of per-call credentials * expanded to include callCredentials. * @param callCredentials A CallCredentials object to associate with this * instance. */ - compose(callCredentials: CallCredentials): ChannelCredentials; + compose(callCredentials: CallCredentials): ChannelCredentials; /** * Gets the set of per-call credentials associated with this instance. */ - getCallCredentials(): CallCredentials; + getCallCredentials(): CallCredentials; /** * Gets a SecureContext object generated from input parameters if this @@ -29,28 +29,28 @@ export interface ChannelCredentials { getSecureContext(): SecureContext|null; } -abstract class ChannelCredentialsImpl implements ChannelCredentials { - protected callCredentials: CallCredentials; +abstract class ChannelCredentialsImpl implements ChannelCredentials { + protected callCredentials: CallCredentials; - protected constructor(callCredentials?: CallCredentials) { + protected constructor(callCredentials?: CallCredentials) { this.callCredentials = callCredentials || CallCredentials.createEmpty(); } - abstract compose(callCredentials: CallCredentials): ChannelCredentialsImpl; + abstract compose(callCredentials: CallCredentials): ChannelCredentialsImpl; - getCallCredentials(): CallCredentials { + getCallCredentials(): CallCredentials { return this.callCredentials; } abstract getSecureContext(): SecureContext|null; } -class InsecureChannelCredentialsImpl extends ChannelCredentialsImpl { - constructor(callCredentials?: CallCredentials) { +class InsecureChannelCredentialsImpl extends ChannelCredentialsImpl { + constructor(callCredentials?: CallCredentials) { super(callCredentials); } - compose(callCredentials: CallCredentials): ChannelCredentialsImpl { + compose(callCredentials: CallCredentials): ChannelCredentialsImpl { throw new Error('Cannot compose insecure credentials'); } @@ -59,15 +59,15 @@ class InsecureChannelCredentialsImpl extends ChannelCredentialsImpl { } } -class SecureChannelCredentialsImpl extends ChannelCredentialsImpl { +class SecureChannelCredentialsImpl extends ChannelCredentialsImpl { secureContext: SecureContext; - constructor(secureContext: SecureContext, callCredentials?: CallCredentials) { + constructor(secureContext: SecureContext, callCredentials?: CallCredentials) { super(callCredentials); this.secureContext = secureContext; } - compose(callCredentials: CallCredentials): ChannelCredentialsImpl { + compose(callCredentials: CallCredentials): ChannelCredentialsImpl { const combinedCallCredentials = this.callCredentials.compose(callCredentials); return new SecureChannelCredentialsImpl( @@ -86,6 +86,7 @@ function verifyIsBufferOrNull(obj: any, friendlyName: string): void { } export namespace ChannelCredentials { + /** * Return a new ChannelCredentials instance with a given set of credentials. * The resulting instance can be used to construct a Channel that communicates @@ -96,7 +97,7 @@ export namespace ChannelCredentials { */ export function createSsl( rootCerts?: Buffer|null, privateKey?: Buffer|null, - certChain?: Buffer|null): ChannelCredentials<{}> { + certChain?: Buffer|null): ChannelCredentials { verifyIsBufferOrNull(rootCerts, 'Root certificate'); verifyIsBufferOrNull(privateKey, 'Private key'); verifyIsBufferOrNull(certChain, 'Certificate chain'); @@ -119,7 +120,7 @@ export namespace ChannelCredentials { /** * Return a new ChannelCredentials instance with no credentials. */ - export function createInsecure(): ChannelCredentials<{}> { + export function createInsecure(): ChannelCredentials { return new InsecureChannelCredentialsImpl(); } } diff --git a/packages/grpc-js-core/src/index.ts b/packages/grpc-js-core/src/index.ts index 7cd93562..4809647f 100644 --- a/packages/grpc-js-core/src/index.ts +++ b/packages/grpc-js-core/src/index.ts @@ -8,11 +8,9 @@ import { Metadata } from './metadata'; import { IncomingHttpHeaders } from 'http'; export interface OAuth2Client { - getRequestMetadata: (url: string) => Promise<{ Authorization: string }>; + getRequestMetadata: (url: string, callback: (err: Error|null, headers?: { Authorization: string }) => void) => void; } -export type GoogleCallCredentials = CallCredentials<{ service_url: string }>; - /**** Client Credentials ****/ // Using assign only copies enumerable properties, which is what we want @@ -22,18 +20,17 @@ export const credentials = Object.assign({ * @param googleCredentials The authentication client to use. * @return The resulting CallCredentials object. */ - createFromGoogleCredential: (googleCredentials: OAuth2Client): GoogleCallCredentials => { - return CallCredentials.createFromMetadataGenerator(async (options, callback) => { - let header; - try { - header = await googleCredentials.getRequestMetadata(options.service_url); - } catch (err) { - callback(err); - return; - } - const metadata = new Metadata(); - metadata.add('authorization', header.Authorization); - callback(null, metadata); + createFromGoogleCredential: (googleCredentials: OAuth2Client): CallCredentials => { + return CallCredentials.createFromMetadataGenerator((options, callback) => { + googleCredentials.getRequestMetadata(options.service_url!, (err, headers) => { + if (err) { + callback(err); + return; + } + const metadata = new Metadata(); + metadata.add('authorization', headers!.Authorization); + callback(null, metadata); + }); }); }, @@ -44,9 +41,9 @@ export const credentials = Object.assign({ * @param callCredentials Any number of CallCredentials objects. * @return The resulting ChannelCredentials object. */ - combineChannelCredentials: ( - channelCredentials: ChannelCredentials, - ...callCredentials: CallCredentials[]): ChannelCredentials => { + combineChannelCredentials: ( + channelCredentials: ChannelCredentials, + ...callCredentials: CallCredentials[]): ChannelCredentials => { return callCredentials.reduce((acc, other) => acc.compose(other), channelCredentials); }, @@ -56,9 +53,9 @@ export const credentials = Object.assign({ * @param additional Any number of additional CallCredentials objects. * @return The resulting CallCredentials object. */ - combineCallCredentials: ( - first: CallCredentials, - ...additional: CallCredentials[]): CallCredentials => { + combineCallCredentials: ( + first: CallCredentials, + ...additional: CallCredentials[]): CallCredentials => { return additional.reduce((acc, other) => acc.compose(other), first); } }, ChannelCredentials, CallCredentials);