├── .eslintignore ├── __tests__ ├── fixtures │ └── empty-options │ │ ├── README.md │ │ └── .vuepress │ │ └── config.js ├── utils │ ├── get-module-fn.js │ ├── get-enhancers.js │ └── preparator.js └── index.spec.js ├── .gitignore ├── .travis.yml ├── lib ├── __mocks__ │ ├── localforage.js │ └── @dynamic │ │ └── vuepress-pass.js ├── generate-hash.js ├── generate-hash.spec.js ├── create-handlers.js ├── enhancer.js ├── enhancer.spec.js ├── create-handlers.spec.js ├── route-guard.js └── route-guard.spec.js ├── .eslintrc.js ├── .editorconfig ├── index.js ├── .release-it.json ├── LICENSE ├── README.md ├── package.json └── CHANGELOG.md /.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | __tests__/fixtures/**/.temp -------------------------------------------------------------------------------- /__tests__/fixtures/empty-options/README.md: -------------------------------------------------------------------------------- 1 | # Hello, VuePress! -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | __tests__/fixtures/**/.temp 3 | .vscode 4 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "8" 4 | - "9" 5 | - "10" 6 | - "node" -------------------------------------------------------------------------------- /__tests__/utils/get-module-fn.js: -------------------------------------------------------------------------------- 1 | module.exports = context => context.pluginAPI.options.clientDynamicModules; 2 | -------------------------------------------------------------------------------- /__tests__/utils/get-enhancers.js: -------------------------------------------------------------------------------- 1 | module.exports = context => context 2 | .pluginAPI 3 | .getOption('enhanceAppFiles'); 4 | -------------------------------------------------------------------------------- /__tests__/fixtures/empty-options/.vuepress/config.js: -------------------------------------------------------------------------------- 1 | const Pass = require('../../../../index'); 2 | 3 | module.exports = { 4 | plugins: [Pass], 5 | }; 6 | -------------------------------------------------------------------------------- /lib/__mocks__/localforage.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | getItem: jest.fn(() => Promise.resolve()), 3 | setItem: jest.fn(() => Promise.resolve()), 4 | } 5 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "extends": "airbnb-base", 3 | "plugins": ["jest"], 4 | "env": { 5 | "jest/globals": true 6 | } 7 | }; -------------------------------------------------------------------------------- /lib/generate-hash.js: -------------------------------------------------------------------------------- 1 | module.exports = function generateHash() { 2 | return Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15); 3 | }; 4 | -------------------------------------------------------------------------------- /lib/__mocks__/@dynamic/vuepress-pass.js: -------------------------------------------------------------------------------- 1 | module.exports.OPTIONS = { 2 | url: 'https://foo.bar/oauth', 3 | redirectUri: 'https://foo.bar/callback', 4 | clientId: 'foobar', 5 | }; 6 | -------------------------------------------------------------------------------- /lib/generate-hash.spec.js: -------------------------------------------------------------------------------- 1 | const hash = require('./generate-hash'); 2 | 3 | describe('generate-hash', () => { 4 | it('generate random strings', () => { 5 | const str1 = hash(); 6 | const str2 = hash(); 7 | expect(str1).not.toEqual(str2); 8 | }); 9 | }); 10 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig helps developers define and maintain consistent 2 | # coding styles between different editors and IDEs 3 | # http://editorconfig.org 4 | 5 | root = true 6 | 7 | [*] 8 | indent_style = space 9 | indent_size = 2 10 | end_of_line = lf 11 | charset = utf-8 12 | trim_trailing_whitespace = true 13 | insert_final_newline = true 14 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-unused-vars */ 2 | const path = require('path'); 3 | 4 | module.exports = (options, context) => ({ 5 | enhanceAppFiles: [path.resolve(__dirname, 'lib/enhancer.js')], 6 | clientDynamicModules: () => ({ 7 | name: 'vuepress-pass', 8 | content: `export const OPTIONS = ${JSON.stringify(options)}`, 9 | }), 10 | }); 11 | -------------------------------------------------------------------------------- /.release-it.json: -------------------------------------------------------------------------------- 1 | { 2 | "git": { 3 | "tagName": "v%s", 4 | "tagAnnotation": "Release v%s", 5 | "commitMessage": "Release v%s" 6 | }, 7 | "github": { 8 | "release": true, 9 | "releaseName": "Release v%s" 10 | }, 11 | "plugins": { 12 | "@release-it/conventional-changelog": { 13 | "preset": "angular", 14 | "infile": "CHANGELOG.md" 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /lib/create-handlers.js: -------------------------------------------------------------------------------- 1 | const URI = require('urijs'); 2 | const localforage = require('localforage'); 3 | 4 | function setState(state) { 5 | return localforage.setItem('auth', state); 6 | } 7 | 8 | function getState() { 9 | return localforage.getItem('auth'); 10 | } 11 | 12 | module.exports = (OPTIONS) => ({ 13 | authenticated: (query, next) => { 14 | return new Promise(resolve => { 15 | if (typeof query === 'string') { 16 | // set auth state in local storage 17 | setState( 18 | URI(query.replace('#', '?')).query(true) 19 | ).then(resolve); 20 | } else { 21 | resolve(); 22 | } 23 | }).then(() => next('/')) 24 | }, 25 | setState, 26 | getState, 27 | }); 28 | -------------------------------------------------------------------------------- /lib/enhancer.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-unused-vars */ 2 | 3 | /* eslint-disable import/no-unresolved */ 4 | const { OPTIONS } = require('@dynamic/vuepress-pass'); 5 | /* eslint-enable import/no-unresolved */ 6 | 7 | const routeGuard = require('./route-guard'); 8 | const createHandlers = require('./create-handlers'); 9 | 10 | module.exports = ({ 11 | Vue, // the version of Vue being used in the VuePress app 12 | options, // the vueOptions for the root Vue instance 13 | router, // the router instance for the app 14 | siteData, // site metadata 15 | isServer, // true if is being server rendered 16 | }) => { 17 | if (isServer) return; 18 | 19 | const beforeRouteHandler = routeGuard({ 20 | ...createHandlers(OPTIONS), 21 | ...OPTIONS, 22 | }, siteData.base); 23 | router.beforeEach(beforeRouteHandler); 24 | }; 25 | -------------------------------------------------------------------------------- /__tests__/utils/preparator.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const { fs } = require('@vuepress/shared-utils'); 3 | const { createApp } = require('@vuepress/core'); 4 | 5 | module.exports = docsBaseDir => () => { 6 | const docsModeNames = fs.readdirSync(docsBaseDir); 7 | 8 | const docsModes = docsModeNames.map((name) => { 9 | const docsPath = path.resolve(docsBaseDir, name); 10 | const docsTempPath = path.resolve(docsPath, '.vuepress/.temp'); 11 | return { name, docsPath, docsTempPath }; 12 | }); 13 | 14 | return Promise.all(docsModes.map(async ({ docsPath, docsTempPath }) => { 15 | await fs.ensureDir(docsTempPath); 16 | const context = createApp({ 17 | sourceDir: docsPath, 18 | theme: '@vuepress/theme-default', 19 | temp: docsTempPath, 20 | }); 21 | await context.process(); 22 | return { context, docsPath }; 23 | })); 24 | }; 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 InCuca Tecnologia 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /lib/enhancer.spec.js: -------------------------------------------------------------------------------- 1 | const { createLocalVue } = require('@vue/test-utils'); 2 | const enhancer = require('./enhancer'); 3 | const { OPTIONS } = require('./__mocks__/@dynamic/vuepress-pass'); 4 | 5 | jest.mock('./create-handlers', () => () => ({ foo: 'bar' })); 6 | jest.mock('./route-guard', () => plgOpts => () => plgOpts); 7 | 8 | describe('enhancer', () => { 9 | it('adds the route guard with given options', (done) => { 10 | const Vue = createLocalVue(); 11 | const beforeEach = (guard) => { 12 | const guardOptions = guard(); 13 | expect(guardOptions).toMatchObject({ 14 | foo: 'bar', 15 | ...OPTIONS, 16 | }); 17 | done(); 18 | }; 19 | enhancer({ 20 | Vue, 21 | options: {}, 22 | router: { beforeEach }, 23 | siteData: {} 24 | }); 25 | }); 26 | 27 | it('does not add route guard if is being server rendered', () => { 28 | const Vue = createLocalVue(); 29 | const beforeEach = jest.fn(); 30 | enhancer({ 31 | Vue, 32 | options: {}, 33 | isServer: true, 34 | router: { beforeEach }, 35 | siteData: {} 36 | }); 37 | expect(beforeEach).not.toHaveBeenCalled(); 38 | }); 39 | }); 40 | -------------------------------------------------------------------------------- /lib/create-handlers.spec.js: -------------------------------------------------------------------------------- 1 | jest.mock('localforage'); 2 | 3 | const createHandlers = require('./create-handlers'); 4 | const localforage = require('localforage'); 5 | 6 | describe('create-handlers', () => { 7 | 8 | beforeEach(() => { 9 | jest.clearAllMocks().resetModules(); 10 | }); 11 | 12 | it('call next and set localforage on authenticated callback', async () => { 13 | const options = createHandlers(); 14 | const next = jest.fn(); 15 | 16 | expect(options.getState).toBeDefined(); 17 | expect(options.setState).toBeDefined(); 18 | 19 | await options.authenticated('#foo=bar', next); 20 | expect(localforage.setItem).toBeCalledWith( 21 | 'auth', 22 | expect.objectContaining({foo: 'bar'}) 23 | ); 24 | expect(next).toBeCalledWith('/'); 25 | }); 26 | 27 | it('call next and on authenticated callback', async () => { 28 | const options = createHandlers(); 29 | const next = jest.fn(); 30 | 31 | expect(options.getState).toBeDefined(); 32 | expect(options.setState).toBeDefined(); 33 | 34 | await options.authenticated({foo: 'bar'}, next); 35 | expect(localforage.setItem).not.toBeCalled(); 36 | expect(next).toBeCalledWith('/'); 37 | }); 38 | }); 39 | -------------------------------------------------------------------------------- /lib/route-guard.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-unused-vars */ 2 | const URI = require('urijs'); 3 | const hash = require('./generate-hash'); 4 | 5 | function isCallback(route, cbURL, base) { 6 | const cbURI = URI(cbURL); 7 | const cbPath = cbURI.path(); 8 | const routeFullPath = URI.joinPaths(base, route.path).toString(); 9 | return cbPath === routeFullPath; 10 | } 11 | 12 | module.exports = function routeGuard(pluginOptions, base = '/') { 13 | const opts = { 14 | unauthenticated: (url, redirect) => redirect(url), 15 | authenticated: (_, next) => next('/'), 16 | getState: () => {}, 17 | setState: () => {}, 18 | ...pluginOptions, 19 | }; 20 | const { redirectUri, clientId } = opts; 21 | const unauthURI = URI(opts.url).query({ 22 | response_type: 'token', 23 | state: hash(), 24 | redirect_uri: redirectUri, 25 | client_id: clientId, 26 | }); 27 | return async (to, from, next) => { 28 | const authState = await opts.getState(); 29 | 30 | const redirect = (url) => { 31 | next(false); 32 | window.location.assign(url); 33 | }; 34 | // console.log('route guard', opts); 35 | 36 | if (isCallback(to, opts.redirectUri, base)) { 37 | opts.authenticated(to.fullPath, next); 38 | } else if (!authState) { 39 | opts.unauthenticated(unauthURI.toString(), redirect); 40 | } else { 41 | next(); 42 | } 43 | }; 44 | }; 45 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # VuePress Pass 2 | 3 | [![Travis](https://img.shields.io/travis/InCuca/vuepress-pass/master.svg)](https://travis-ci.org/InCuca/vuepress-pass/branches) 4 | 5 | > VuePress oAuth2 - Implicity Grant plugin 6 | 7 | Another options (behind a proxy server): [Pomerium](https://www.pomerium.io), [Okta](https://scotch.io/tutorials/add-authentication-and-personalization-to-vuepress), [vuepress-pomerium](https://github.com/InCuca/vuepress-pomerium) 8 | 9 | ## Usage 10 | 11 | `npm i --save InCuca/vuepress-pass` 12 | 13 | .vuepress/config.js: 14 | 15 | ```js 16 | const Pass = require('vuepress-pass'); 17 | 18 | module.exports = { 19 | plugins: [ 20 | [Pass, { 21 | url: 'https://foo.bar/oauth', 22 | redirectUri: 'https://foo.bar/callback', 23 | clientId: 'foobar', 24 | authenticated(redirectQuery, redirect) { redirect('/'); }, // optional 25 | unauthenticated(authQuery, redirect) { redirect(authQuery); }, // optional 26 | setState(state) { localStorage.setItem('auth', state); }, // optional 27 | getState() { return localStorage.getItem('auth'); }, // optional 28 | }], 29 | ] 30 | }; 31 | ``` 32 | 33 | * **authenticated** is called when user comes back from provider authentication 34 | * **unauthenticated** is called when user need's authentication on provide and will redirect (through redirect function) 35 | 36 | [more details](https://vuepress.vuejs.org/plugin/using-a-plugin.html#using-a-plugin) 37 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vuepress-pass", 3 | "version": "1.1.1", 4 | "description": "VuePress authentication plugin", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "jest", 8 | "release": "release-it" 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "git+https://github.com/InCuca/vuepress-pass.git" 13 | }, 14 | "keywords": [ 15 | "vuepress", 16 | "plugin", 17 | "password", 18 | "auth", 19 | "gitlab" 20 | ], 21 | "author": "Walker at incuca.com.br", 22 | "license": "MIT", 23 | "bugs": { 24 | "url": "https://github.com/InCuca/vuepress-pass/issues" 25 | }, 26 | "homepage": "https://github.com/InCuca/vuepress-pass#readme", 27 | "devDependencies": { 28 | "@release-it/conventional-changelog": "^1.0.0", 29 | "@vue/test-utils": "^1.0.0-beta.29", 30 | "@vuepress/core": "^1.0.0-alpha.47", 31 | "@vuepress/shared-utils": "^1.0.0-alpha.47", 32 | "@vuepress/theme-default": "^1.0.0-alpha.47", 33 | "eslint": "^5.9.0", 34 | "eslint-config-airbnb-base": "^13.1.0", 35 | "eslint-plugin-import": "^2.14.0", 36 | "eslint-plugin-jest": "^22.1.0", 37 | "jest": "^23.6.0", 38 | "release-it": "^11.0.0-alpha.7", 39 | "vue-router": "^3.0.2" 40 | }, 41 | "jest": { 42 | "testPathIgnorePatterns": [ 43 | "/node_modules/", 44 | "/__tests__/utils/", 45 | "/__tests__/fixtures/", 46 | ".temp" 47 | ] 48 | }, 49 | "dependencies": { 50 | "urijs": "^1.19.1" 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /__tests__/index.spec.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const fs = require('fs'); 3 | const preparator = require('./utils/preparator'); 4 | const getEnhancers = require('./utils/get-enhancers'); 5 | const getModuleFn = require('./utils/get-module-fn'); 6 | 7 | const docsBaseDir = path.resolve(__dirname, 'fixtures'); 8 | const doPrepare = preparator(docsBaseDir); 9 | 10 | describe('Pass', () => { 11 | it('should not throw error', async () => { 12 | const docs = await doPrepare(docsBaseDir); 13 | docs.forEach(({ context, docsPath }) => { 14 | expect(context.sourceDir).toBe(docsPath); 15 | }); 16 | }); 17 | 18 | it('should add enhancer', async () => { 19 | const docs = await doPrepare(); 20 | docs.forEach(({ context }) => { 21 | const enhancer = getEnhancers(context); 22 | const enhancerSrc = path.resolve(__dirname, '../lib/enhancer.js'); 23 | expect(() => fs.readFileSync(enhancerSrc)).not.toThrow(); 24 | expect(enhancer).toMatchObject({ items: expect.any(Array) }); 25 | expect(enhancer.items).toContainEqual( 26 | expect.objectContaining({ value: enhancerSrc }), 27 | ); 28 | }); 29 | }); 30 | 31 | it('should add vuepress-pass.js module', async () => { 32 | const docs = await doPrepare(); 33 | docs.forEach(({ context }) => { 34 | const modules = getModuleFn(context).appliedItems; 35 | expect(modules).toContainEqual( 36 | expect.objectContaining({ 37 | value: { 38 | name: 'vuepress-pass', 39 | content: expect.stringMatching(/^export const OPTIONS = /), 40 | }, 41 | }), 42 | ); 43 | }); 44 | }); 45 | }); 46 | -------------------------------------------------------------------------------- /lib/route-guard.spec.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-new */ 2 | jest.mock('./generate-hash', () => () => 'foo'); 3 | 4 | const VueRouter = require('vue-router'); 5 | const URI = require('urijs'); 6 | const routeGuard = require('./route-guard'); 7 | 8 | const createRoutes = () => ([ 9 | { path: '/', component: { render: h => h('div') } }, 10 | ]); 11 | 12 | const createOptions = opts => ({ 13 | ...opts, 14 | url: 'https://foo.bar/oauth', 15 | redirectUri: 'https://foo.bar/callback', 16 | clientId: 'foo', 17 | }); 18 | 19 | const createAuthURI = options => URI(options.url).query({ 20 | response_type: 'token', 21 | state: 'foo', 22 | redirect_uri: options.redirectUri, 23 | client_id: options.clientId, 24 | }).toString(); 25 | 26 | describe('route-guard', () => { 27 | it('calls unauthenticated callback', (done) => { 28 | const options = createOptions({ 29 | unauthenticated: jest.fn((uri, redirect) => { 30 | expect(uri).toEqual(expectedUri); 31 | expect(redirect).toBeDefined(); 32 | done(); 33 | }), 34 | }); 35 | const expectedUri = createAuthURI(options); 36 | const router = new VueRouter (createRoutes()); 37 | router.beforeEach(routeGuard(options)); 38 | router.push('/'); 39 | }); 40 | 41 | it('does not calls unauthenticated if auth state is set', async () => { 42 | const state = {}; 43 | const options = createOptions({ 44 | unauthenticated: jest.fn(), 45 | getState: () => Promise.resolve(state), 46 | }); 47 | const next = jest.fn(); 48 | const guard = routeGuard(options); 49 | await guard({ fullPath: '/bar', path: 'bar' }, '/foo', next); 50 | expect(options.unauthenticated).not.toBeCalled(); 51 | }); 52 | 53 | it('redirects to auth URL', (done) => { 54 | const options = createOptions(); 55 | const expectedURI = createAuthURI(options); 56 | const router = new VueRouter(createRoutes()); 57 | const success = jest.fn(); 58 | const error = jest.fn(); 59 | window.location.assign = jest.fn(() => { 60 | expect(success).not.toBeCalled(); 61 | expect(window.location.assign).toBeCalledWith( 62 | expectedURI, 63 | ); 64 | done(); 65 | }); 66 | 67 | router.beforeEach(routeGuard(options)); 68 | router.push('/', success, error); 69 | }); 70 | 71 | it('only call next and none callback if path is notCallback', async () => { 72 | const authenticated = jest.fn(); 73 | const unauthenticated = jest.fn(); 74 | const next = jest.fn(); 75 | const expectedParams = { 76 | access_token: 'foo', 77 | token_type: 'bearer', 78 | state: 'bar', 79 | }; 80 | const options = createOptions({ 81 | getState: () => expectedParams, 82 | authenticated, 83 | unauthenticated, 84 | redirectUri: '/callback', 85 | }); 86 | const guard = routeGuard(options); 87 | await guard({fullPath: '/notCallback', path: 'notCallback'}, '/foo', next); 88 | expect(authenticated).not.toBeCalled(); 89 | expect(unauthenticated).not.toBeCalled(); 90 | expect(next).toBeCalled(); 91 | }); 92 | 93 | it('calls authenticated callback if is callback', async () => { 94 | const authenticated = jest.fn(); 95 | const options = createOptions({ 96 | authenticated, 97 | redirectUri: '/callback', 98 | }); 99 | const next = jest.fn(); 100 | const guard = routeGuard(options); 101 | await guard({fullPath: '/callback', path: 'callback'}, '/foo', next); 102 | expect(authenticated).toBeCalledWith('/callback', next); 103 | }); 104 | }); 105 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## [1.1.1](https://github.com/InCuca/vuepress-pass/compare/v1.1.0...v1.1.1) (2019-05-07) 2 | 3 | # 1.0.0 (2018-12-17) 4 | 5 | 6 | ### Bug Fixes 7 | 8 | * **enhancer:** fix enhancer options to routeGuard ([dae9708](https://github.com/InCuca/vuepress-pass/commit/dae9708)) 9 | * **release-it:** fix build command ([2cd4051](https://github.com/InCuca/vuepress-pass/commit/2cd4051)) 10 | * **route-guard:** calls assign after next ([4e38de2](https://github.com/InCuca/vuepress-pass/commit/4e38de2)) 11 | 12 | 13 | ### Features 14 | 15 | * **changelog:** add changelog ([2c53722](https://github.com/InCuca/vuepress-pass/commit/2c53722)) 16 | * **create-handlers:** add authState on authenticated ([4626903](https://github.com/InCuca/vuepress-pass/commit/4626903)) 17 | * **enhancer:** add enhancer module ([8ab403f](https://github.com/InCuca/vuepress-pass/commit/8ab403f)) 18 | * **eslint:** add eslint settings ([4c2ae56](https://github.com/InCuca/vuepress-pass/commit/4c2ae56)) 19 | * **eslint:** add jest plugin ([f37438b](https://github.com/InCuca/vuepress-pass/commit/f37438b)) 20 | * **index:** add enhancer ([1fba218](https://github.com/InCuca/vuepress-pass/commit/1fba218)) 21 | * **package:** update package metadata ([93dc73f](https://github.com/InCuca/vuepress-pass/commit/93dc73f)) 22 | * **Pass:** add pass plugin tests ([eb1cc0f](https://github.com/InCuca/vuepress-pass/commit/eb1cc0f)) 23 | * **plugin:** add fixture for default config ([f32a34b](https://github.com/InCuca/vuepress-pass/commit/f32a34b)) 24 | * **plugin:** add options dynamic module ([32354a6](https://github.com/InCuca/vuepress-pass/commit/32354a6)) 25 | * **route-guard:** add authenticated callback ([1faa1f8](https://github.com/InCuca/vuepress-pass/commit/1faa1f8)) 26 | * **route-guard:** add guard ([0ecb215](https://github.com/InCuca/vuepress-pass/commit/0ecb215)) 27 | * **route-guard:** add redirect to auth URL ([e96bd0b](https://github.com/InCuca/vuepress-pass/commit/e96bd0b)) 28 | * **route-guard:** add response_type rfc6749 ([7494eeb](https://github.com/InCuca/vuepress-pass/commit/7494eeb)) 29 | * **route-guard:** add state hash ([4b334a3](https://github.com/InCuca/vuepress-pass/commit/4b334a3)) 30 | * **route-guard:** add unauthenticated callback ([b5ead02](https://github.com/InCuca/vuepress-pass/commit/b5ead02)) 31 | * **route-guard:** add unauthenticated test ([d566673](https://github.com/InCuca/vuepress-pass/commit/d566673)) 32 | * **travis:** add config ([10bd267](https://github.com/InCuca/vuepress-pass/commit/10bd267)) 33 | * **travis:** add node stable ([f5a2857](https://github.com/InCuca/vuepress-pass/commit/f5a2857)) 34 | * **travis:** add node vuepress versions ([20a5386](https://github.com/InCuca/vuepress-pass/commit/20a5386)) 35 | 36 | 37 | 38 | # 1.0.0 (2018-12-17) 39 | 40 | 41 | ### Bug Fixes 42 | 43 | * **enhancer:** fix enhancer options to routeGuard ([dae9708](https://github.com/InCuca/vuepress-pass/commit/dae9708)) 44 | * **release-it:** fix build command ([2cd4051](https://github.com/InCuca/vuepress-pass/commit/2cd4051)) 45 | * **route-guard:** calls assign after next ([4e38de2](https://github.com/InCuca/vuepress-pass/commit/4e38de2)) 46 | 47 | 48 | ### Features 49 | 50 | * **changelog:** add changelog ([2c53722](https://github.com/InCuca/vuepress-pass/commit/2c53722)) 51 | * **create-handlers:** add authState on authenticated ([4626903](https://github.com/InCuca/vuepress-pass/commit/4626903)) 52 | * **enhancer:** add enhancer module ([8ab403f](https://github.com/InCuca/vuepress-pass/commit/8ab403f)) 53 | * **eslint:** add eslint settings ([4c2ae56](https://github.com/InCuca/vuepress-pass/commit/4c2ae56)) 54 | * **eslint:** add jest plugin ([f37438b](https://github.com/InCuca/vuepress-pass/commit/f37438b)) 55 | * **index:** add enhancer ([1fba218](https://github.com/InCuca/vuepress-pass/commit/1fba218)) 56 | * **package:** update package metadata ([93dc73f](https://github.com/InCuca/vuepress-pass/commit/93dc73f)) 57 | * **Pass:** add pass plugin tests ([eb1cc0f](https://github.com/InCuca/vuepress-pass/commit/eb1cc0f)) 58 | * **plugin:** add fixture for default config ([f32a34b](https://github.com/InCuca/vuepress-pass/commit/f32a34b)) 59 | * **plugin:** add options dynamic module ([32354a6](https://github.com/InCuca/vuepress-pass/commit/32354a6)) 60 | * **route-guard:** add authenticated callback ([1faa1f8](https://github.com/InCuca/vuepress-pass/commit/1faa1f8)) 61 | * **route-guard:** add guard ([0ecb215](https://github.com/InCuca/vuepress-pass/commit/0ecb215)) 62 | * **route-guard:** add redirect to auth URL ([e96bd0b](https://github.com/InCuca/vuepress-pass/commit/e96bd0b)) 63 | * **route-guard:** add response_type rfc6749 ([7494eeb](https://github.com/InCuca/vuepress-pass/commit/7494eeb)) 64 | * **route-guard:** add state hash ([4b334a3](https://github.com/InCuca/vuepress-pass/commit/4b334a3)) 65 | * **route-guard:** add unauthenticated callback ([b5ead02](https://github.com/InCuca/vuepress-pass/commit/b5ead02)) 66 | * **route-guard:** add unauthenticated test ([d566673](https://github.com/InCuca/vuepress-pass/commit/d566673)) 67 | * **travis:** add config ([10bd267](https://github.com/InCuca/vuepress-pass/commit/10bd267)) 68 | * **travis:** add node stable ([f5a2857](https://github.com/InCuca/vuepress-pass/commit/f5a2857)) 69 | * **travis:** add node vuepress versions ([20a5386](https://github.com/InCuca/vuepress-pass/commit/20a5386)) 70 | 71 | 72 | 73 | # 0.1.0 (2018-12-17) 74 | 75 | 76 | ### Bug Fixes 77 | 78 | * **enhancer:** fix enhancer options to routeGuard ([dae9708](https://github.com/InCuca/vuepress-pass/commit/dae9708)) 79 | * **route-guard:** calls assign after next ([4e38de2](https://github.com/InCuca/vuepress-pass/commit/4e38de2)) 80 | 81 | 82 | ### Features 83 | 84 | * **enhancer:** add enhancer module ([8ab403f](https://github.com/InCuca/vuepress-pass/commit/8ab403f)) 85 | * **eslint:** add eslint settings ([4c2ae56](https://github.com/InCuca/vuepress-pass/commit/4c2ae56)) 86 | * **eslint:** add jest plugin ([f37438b](https://github.com/InCuca/vuepress-pass/commit/f37438b)) 87 | * **index:** add enhancer ([1fba218](https://github.com/InCuca/vuepress-pass/commit/1fba218)) 88 | * **package:** update package metadata ([93dc73f](https://github.com/InCuca/vuepress-pass/commit/93dc73f)) 89 | * **Pass:** add pass plugin tests ([eb1cc0f](https://github.com/InCuca/vuepress-pass/commit/eb1cc0f)) 90 | * **plugin:** add fixture for default config ([f32a34b](https://github.com/InCuca/vuepress-pass/commit/f32a34b)) 91 | * **plugin:** add options dynamic module ([32354a6](https://github.com/InCuca/vuepress-pass/commit/32354a6)) 92 | * **route-guard:** add authenticated callback ([1faa1f8](https://github.com/InCuca/vuepress-pass/commit/1faa1f8)) 93 | * **route-guard:** add guard ([0ecb215](https://github.com/InCuca/vuepress-pass/commit/0ecb215)) 94 | * **route-guard:** add redirect to auth URL ([e96bd0b](https://github.com/InCuca/vuepress-pass/commit/e96bd0b)) 95 | * **route-guard:** add response_type rfc6749 ([7494eeb](https://github.com/InCuca/vuepress-pass/commit/7494eeb)) 96 | * **route-guard:** add state hash ([4b334a3](https://github.com/InCuca/vuepress-pass/commit/4b334a3)) 97 | * **route-guard:** add unauthenticated callback ([b5ead02](https://github.com/InCuca/vuepress-pass/commit/b5ead02)) 98 | * **route-guard:** add unauthenticated test ([d566673](https://github.com/InCuca/vuepress-pass/commit/d566673)) 99 | * **travis:** add config ([10bd267](https://github.com/InCuca/vuepress-pass/commit/10bd267)) 100 | * **travis:** add node stable ([f5a2857](https://github.com/InCuca/vuepress-pass/commit/f5a2857)) 101 | * **travis:** add node vuepress versions ([20a5386](https://github.com/InCuca/vuepress-pass/commit/20a5386)) 102 | 103 | 104 | 105 | --------------------------------------------------------------------------------