Skip to content
Closed
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion e2e/fastify.e2e-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ describe('Fastify Swagger', () => {
.addOAuth2()
.addApiKey()
.addApiKey({ type: 'apiKey' }, 'key1')
.addApiKey({ type: 'apiKey' }, 'key2')
.addApiKey({}, 'key2')
.addApiKey('key3', { type: 'apiKey' })
.addCookieAuth()
.addSecurityRequirements('bearer')
.addSecurityRequirements({ basic: [], cookie: [] });
Expand Down
4 changes: 2 additions & 2 deletions e2e/validate-schema.e2e-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ describe('Validate OpenAPI schema', () => {
.addBearerAuth()
.addOAuth2()
.addApiKey()
.addApiKey({ type: 'apiKey' }, 'key1')
.addApiKey({ type: 'apiKey' }, 'key2')
.addApiKey({}, 'key1')
.addApiKey({}, 'key2')
.addCookieAuth()
.addSecurityRequirements('bearer')
.addSecurityRequirements({ basic: [], cookie: [] })
Expand Down
152 changes: 115 additions & 37 deletions lib/document-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,18 @@ import { isString, isUndefined, negate, pickBy } from 'lodash';
import { buildDocumentBase } from './fixtures/document.base';
import { OpenAPIObject } from './interfaces';
import {
ApiKeySchemeObject,
ExternalDocumentationObject,
HttpSchemeObject,
OAuth2SchemeObject,
SecurityRequirementObject,
SecuritySchemeObject,
ServerVariableObject,
TagObject
} from './interfaces/open-api-spec.interface';

type Optional<T, K extends keyof T> = Pick<Partial<T>, K> & Omit<T, K>;

export class DocumentBuilder {
private readonly logger = new Logger(DocumentBuilder.name);
private readonly document: Omit<OpenAPIObject, 'paths'> = buildDocumentBase();
Expand Down Expand Up @@ -110,74 +115,147 @@ export class DocumentBuilder {
}

public addBearerAuth(
options: SecuritySchemeObject = {
type: 'http'
},
name = 'bearer'
name?: string,
options?: Partial<Optional<HttpSchemeObject, 'type'>>
): this;
/**
* @deprecated Use `addBearerAuth(name, options)` instead
*/
public addBearerAuth(
options?: Partial<Optional<HttpSchemeObject, 'type'>>,
name?: string
): this;
public addBearerAuth(
nameOrOptions:
| string
| Partial<Optional<HttpSchemeObject, 'type'>> = 'bearer',
optionsOrName: string | Partial<Optional<HttpSchemeObject, 'type'>> = {}
): this {
this.addSecurity(name, {
if (typeof nameOrOptions === 'object') {
[nameOrOptions, optionsOrName] = [optionsOrName, nameOrOptions];
}
this.addSecurity(nameOrOptions as string, {
type: 'http',
scheme: 'bearer',
bearerFormat: 'JWT',
...options
...(optionsOrName as any)
});
return this;
}

public addOAuth2(
options: SecuritySchemeObject = {
type: 'oauth2'
},
name = 'oauth2'
name?: string,
options?: Partial<Optional<OAuth2SchemeObject, 'type'>>
): this;
/**
* @deprecated Use `addOAuth2(name, options)` instead
*/
public addOAuth2(
options?: Partial<Optional<OAuth2SchemeObject, 'type'>>,
name?: string
): this;
public addOAuth2(
nameOrOptions:
| string
| Partial<Optional<OAuth2SchemeObject, 'type'>> = 'oauth2',
optionsOrName: string | Partial<Optional<OAuth2SchemeObject, 'type'>> = {}
): this {
this.addSecurity(name, {
if (typeof nameOrOptions === 'object') {
[nameOrOptions, optionsOrName] = [optionsOrName, nameOrOptions];
}
this.addSecurity(nameOrOptions as string, {
type: 'oauth2',
flows: {},
...options
...(optionsOrName as any)
Comment thread
xTCry marked this conversation as resolved.
Outdated
});
return this;
}

public addApiKey(
options: SecuritySchemeObject = {
type: 'apiKey'
},
name = 'api_key'
public addBasicAuth(
name?: string,
options?: Partial<Optional<HttpSchemeObject, 'type'>>
): this;
/**
* @deprecated Use `addBasicAuth(name, options)` instead
*/
public addBasicAuth(
options?: Partial<Optional<HttpSchemeObject, 'type'>>,
name?: string
): this;
public addBasicAuth(
nameOrOptions:
| string
| Partial<Optional<HttpSchemeObject, 'type'>> = 'basic',
optionsOrName: string | Partial<Optional<HttpSchemeObject, 'type'>> = {}
): this {
this.addSecurity(name, {
type: 'apiKey',
in: 'header',
name,
...options
if (typeof nameOrOptions === 'object') {
[nameOrOptions, optionsOrName] = [optionsOrName, nameOrOptions];
}
this.addSecurity(nameOrOptions as string, {
type: 'http',
scheme: 'basic',
...(optionsOrName as any)
});
return this;
}

public addBasicAuth(
options: SecuritySchemeObject = {
type: 'http'
},
name = 'basic'
public addApiKey(
name?: string,
options?: Partial<Optional<ApiKeySchemeObject, 'type'>>
): this;
/**
* @deprecated Use `addApiKey(name, options)` instead
*/
public addApiKey(
options?: Partial<Optional<ApiKeySchemeObject, 'type'>>,
name?: string
): this;
public addApiKey(
nameOrOptions:
| string
| Partial<Optional<ApiKeySchemeObject, 'type'>> = 'api_key',
optionsOrName: string | Partial<Optional<ApiKeySchemeObject, 'type'>> = {}
): this {
this.addSecurity(name, {
type: 'http',
scheme: 'basic',
...options
if (typeof nameOrOptions === 'object') {
[nameOrOptions, optionsOrName] = [optionsOrName, nameOrOptions];
}
this.addSecurity(nameOrOptions as string, {
type: 'apiKey',
in: 'header',
name: nameOrOptions,
...(optionsOrName as any)
});
return this;
}

public addCookieAuth(
cookieName?: string,
name?: string,
options?: Partial<Optional<ApiKeySchemeObject, 'type'>>
): this;
/**
* @deprecated Use `addCookieAuth(cookieName, name, options)` instead
*/
public addCookieAuth(
cookieName: string,
options?: Partial<Optional<ApiKeySchemeObject, 'type'>>,
name?: string
): this;
public addCookieAuth(
cookieName = 'connect.sid',
options: SecuritySchemeObject = {
type: 'apiKey'
},
securityName = 'cookie'
nameOrOptions:
| string
| Partial<Optional<ApiKeySchemeObject, 'type'>> = 'cookie',
optionsOrName: string | Partial<Optional<ApiKeySchemeObject, 'type'>> = {}
): this {
this.addSecurity(securityName, {
if (typeof nameOrOptions === 'object') {
[nameOrOptions, optionsOrName] = [optionsOrName, nameOrOptions];
}
this.addSecurity(nameOrOptions as string, {
type: 'apiKey',
in: 'cookie',
name: cookieName,
...options
...(optionsOrName as any)
});
return this;
}
Expand Down
35 changes: 28 additions & 7 deletions lib/interfaces/open-api-spec.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -250,16 +250,37 @@ export interface XmlObject {
}

export type SecuritySchemeType = 'apiKey' | 'http' | 'oauth2' | 'openIdConnect';
export type ApiKeyLocation = 'query' | 'header' | 'cookie';

export interface SecuritySchemeObject {
type: SecuritySchemeType;
export type SecuritySchemeObject =
| ApiKeySchemeObject
| HttpSchemeObject
| OAuth2SchemeObject
| OpenIdConnectSchemeObject;

export interface ApiKeySchemeObject {
type: 'apiKey';
description?: string;
name?: string;
in?: string;
scheme?: string;
name: string;
in: ApiKeyLocation;
}

export interface HttpSchemeObject {
type: 'http';
description?: string;
scheme: string;
bearerFormat?: string;
flows?: OAuthFlowsObject;
openIdConnectUrl?: string;
}
export interface OAuth2SchemeObject {
type: 'oauth2';
description?: string;
flows: OAuthFlowsObject;
}

export interface OpenIdConnectSchemeObject {
type: 'openIdConnect';
description?: string;
openIdConnectUrl: string;
}

export interface OAuthFlowsObject {
Expand Down