Skip to content

Commit

Permalink
refactor: cleanup codebase
Browse files Browse the repository at this point in the history
  • Loading branch information
thetutlage committed Mar 6, 2020
1 parent 214bd53 commit 5ea3047
Show file tree
Hide file tree
Showing 22 changed files with 395 additions and 291 deletions.
9 changes: 9 additions & 0 deletions adonis-typings/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,11 @@
/*
* @adonisjs/shield
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

/// <reference path="./shield.ts" />
/// <reference path="./context.ts" />
55 changes: 41 additions & 14 deletions adonis-typings/shield.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,12 @@
*/

declare module '@ioc:Adonis/Addons/Shield' {
import { CookieOptions } from '@poppinss/cookie'
import { CspOptions as HelmetCspOptions } from 'helmet-csp/dist/lib/types'

/**
* Config for `X-Frame-Options` header
*/
export type XFrameOptions = {
enabled: boolean,
action?: 'DENY' | 'SAMEORIGIN',
Expand All @@ -19,51 +23,74 @@ declare module '@ioc:Adonis/Addons/Shield' {
domain: string,
}

// X-Content-Type-Options
/**
* Config for X-Content-Type-Options
*/
export type ContentTypeSniffingOptions = {
enabled: boolean,
}

// HTTP Strict Transport Security (HSTS)
/**
* Config for HTTP Strict Transport Security (HSTS)
*/
export type HstsOptions = {
enabled: boolean,
maxAge?: string | number,
includeSubDomains?: boolean,
preload?: boolean,
}

// X-XSS-Protection
/**
* Config for X-XSS-Protection
*/
export type XSSOptions = {
enabled: boolean,
enableOnOldIE?: boolean,
reportUri?: string,
mode?: 'block' | null,
}

// X-Download-Options
/**
* Config for X-Download-Options
*/
export type IENoOpenOptions = {
enabled: boolean,
}

// X-DNS-Prefetch-Control
/**
* Config for X-DNS-Prefetch-Control
*/
export type DnsPrefetchOptions = {
enabled: boolean,
allow?: boolean,
}

export type CspOptions = {
enabled: boolean,
} & HelmetCspOptions
/**
* Config for working with CSP
*/
export type CspOptions = { enabled: boolean } & HelmetCspOptions

/**
* Config for working with CSRF options
*/
export type CsrfOptions = {
enabled: boolean,
exceptRoutes?: string[],
methods?: ReadonlyArray<string>,
cookieOptions?: {
httpOnly?: boolean,
sameSite?: boolean,
path?: string,
maxAge?: number
}
cookieOptions?: Partial<CookieOptions>,
}

/**
* Shield config file types
*/
export type ShieldConfig = {
xFrame: XFrameOptions,
contentTypeSniffing: ContentTypeSniffingOptions,
hsts: HstsOptions,
xss: XSSOptions,
noOpen: IENoOpenOptions,
dnsPrefetch: DnsPrefetchOptions,
csp: CspOptions,
csrf: CsrfOptions,
}
}
47 changes: 47 additions & 0 deletions src/ShieldMiddleware/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* @adonisjs/shield
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

import { ShieldConfig } from '@ioc:Adonis/Addons/Shield'
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'

import * as shield from '../../standalone'

/**
* Shield middleware to protect web applications against common
* web attacks
*/
export class ShieldMiddleware {
/**
* Actions to be performed
*/
private actions = [
shield.csrfFactory(this.config.csrf || {}, ''),
shield.cspFactory(this.config.csp || {}),
shield.dnsPrefetchFactory(this.config.dnsPrefetch || {}),
shield.frameGuardFactory(this.config.xFrame || {}),
shield.hstsFactory(this.config.hsts || {}),
shield.noOpenFactory(this.config.noOpen || {}),
shield.noSniffFactory(this.config.contentTypeSniffing || {}),
shield.xssFactory(this.config.xss || {}),
]

constructor (private config: ShieldConfig) {
}

/**
* Handle request
*/
public async handle (ctx: HttpContextContract, next: () => Promise<void>) {
for (let action of this.actions) {
await action(ctx)
}

await next()
}
}
16 changes: 11 additions & 5 deletions src/csp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,15 @@ import { SourceListDirective } from 'helmet-csp/dist/lib/types'

import { CspOptions } from '@ioc:Adonis/Addons/Shield'
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'

import { noop } from './noop'

/**
* Reads `nonce` from the ServerResponse and returns appropriate
* string
*/
function nonceFn (_req, res) {
return `'nonce-${res['nonce']}'`
function nonceFn (_: any, response: HttpContextContract['response']['response']) {
return `'nonce-${response['nonce']}'`
}

/**
Expand All @@ -42,9 +43,10 @@ function transformNonceKeywords (directive: SourceListDirective): SourceListDire
}

/**
* Adds `Content-Security-Policy` header based upon given user options
* Factory that returns a function to set the `Content-Security-Policy` header based upon
* the user config
*/
export function csp (options: CspOptions) {
export function cspFactory (options: CspOptions) {
if (!options.enabled) {
return noop
}
Expand All @@ -60,7 +62,11 @@ export function csp (options: CspOptions) {
}

const helmetCspMiddleware = helmetCsp(options)
return function cspMiddlewareFn ({ response }: HttpContextContract) {

return function csp ({ response }: HttpContextContract) {
/**
* Helmet csp needs the `nonce` property on the HTTP ServerResponse
*/
response.response['nonce'] = response.nonce
helmetCspMiddleware(response.request, response.response, () => {})
}
Expand Down

0 comments on commit 5ea3047

Please sign in to comment.