Skip to content

Commit

Permalink
Merge branch 'dev'
Browse files Browse the repository at this point in the history
  • Loading branch information
pooya parsa committed Mar 15, 2020
2 parents ac2e649 + 6ba12a9 commit 56c247c
Show file tree
Hide file tree
Showing 15 changed files with 4,680 additions and 3,505 deletions.
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,15 @@

All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.

### [4.8.5](https://github.com/nuxt-community/auth-module/compare/v4.8.4...v4.8.5) (2019-12-27)


### Bug Fixes

* **core:** always return boolean form hasScope ([a2da3a4](https://github.com/nuxt-community/auth-module/commit/a2da3a4775266aee859c48763b3c3788efe08f02))
* **core:** support querystring only url for `isRelativeURL` ([#492](https://github.com/nuxt-community/auth-module/issues/492)) ([09d81ea](https://github.com/nuxt-community/auth-module/commit/09d81ead05c11bcd453ad59c3796987872787a12))
* **module:** always transpile nanoiid ([8ef5a9b](https://github.com/nuxt-community/auth-module/commit/8ef5a9bf6cff886be2dfc49855cf5c7c4cb1c670)), closes [#472](https://github.com/nuxt-community/auth-module/issues/472)

### [4.8.4](https://github.com/nuxt-community/auth-module/compare/v4.8.3...v4.8.4) (2019-09-12)


Expand Down
2 changes: 1 addition & 1 deletion docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@
"build": "vuepress build"
},
"devDependencies": {
"vuepress": "^1.1.0"
"vuepress": "^1.3.1"
}
}
6 changes: 3 additions & 3 deletions docs/providers/auth0.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ User will be redirected to a page like this:

`client_id` and `domain` are **REQUIRED**. Your application needs some details about this client to communicate with Auth0.

`audience` is required _unless_ you've explicitly set a default audience [on your Auth0 tenent](https://manage.auth0.com/#/tenant).
`audience` is required _unless_ you've explicitly set a default audience [on your Auth0 tenant](https://manage.auth0.com/#/tenant).

You can get your `client_id` and `domain` the Settings section for your client in the [Auth0 API dashboard](https://manage.auth0.com/#/applications). Your audience is defined on your [client's API](https://manage.auth0.com/#/apis).

Expand All @@ -47,7 +47,7 @@ You can get your `client_id` and `domain` the Settings section for your client i

Auth0 tenants created in 2018 and earlier had an optional tenant setting `Enable Seamless SSO`. This setting is automatically enabled for new tenants and cannot be disabled.

If enabled and a user logs out and logs back in a short while later, they will not need to re-enter their credentials. They'll be logged in automatically.
If enabled and a user logs out and logs back in a short while later, they will not need to re-enter their credentials. They'll be logged in automatically.

You can force Auth0 to present the login page:
* Go to into the `Tenant Settings` > `Advanced`
Expand All @@ -58,7 +58,7 @@ Wherever you have a logout feature do two things:
```js
this.$auth.logout()
```
2. redirect the user to the Auth0 logout URL along with a `returnTo` parameter
2. redirect the user to the Auth0 logout URL along with a `returnTo` parameter
```
https://mytenant.auth0.com/v2/logout?returnTo=http%3A%2F%2Flocalhost:3000
```
7 changes: 7 additions & 0 deletions docs/schemes/local.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ auth: {
},
// tokenRequired: true,
// tokenType: 'bearer'
// autoFetchUser: true
}
}
}
Expand Down Expand Up @@ -117,3 +118,9 @@ This option can be used to disable all token handling. Useful for Cookie only fl
- Default: `Bearer`

Authorization header type to be used in axios requests.

### `autoFetchUser`

- Default: `true`

This option can be used to disable user fetch after login. It is useful when your login response already have the user.
2,150 changes: 1,365 additions & 785 deletions docs/yarn.lock

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions examples/demo/layouts/default.vue
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,14 @@
</template>

<script>
import dotProp from 'dotprop'
import get from 'lodash.get'
export default {
computed: {
picture() {
return dotProp(this.$auth.user, 'picture') || // OpenID
dotProp(this.$auth.user, 'picture.data.url') || // Facebook graph API
dotProp(this.$auth.user, 'avatar_url') // GitHub
return get(this.$auth.user, 'picture') || // OpenID
get(this.$auth.user, 'picture.data.url') || // Facebook graph API
get(this.$auth.user, 'avatar_url') // GitHub
}
}
Expand Down
41 changes: 26 additions & 15 deletions lib/core/auth.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import getProp from 'dotprop'

import Storage from './storage'
import { routeOption, isRelativeURL, isSet, isSameURL } from './utilities'
import { routeOption, isRelativeURL, isSet, isSameURL, getProp } from './utilities'

export default class Auth {
constructor (ctx, options) {
Expand Down Expand Up @@ -130,10 +128,11 @@ export default class Auth {
return Promise.resolve()
}

return this.wrapLogin(this.strategy.login(...arguments)).catch(error => {
this.callOnError(error, { method: 'login' })
return Promise.reject(error)
})
return this.wrapLogin(this.strategy.login(...arguments))
.catch(error => {
this.callOnError(error, { method: 'login' })
return Promise.reject(error)
})
}

fetchUser () {
Expand Down Expand Up @@ -261,19 +260,30 @@ export default class Auth {
return this.$storage.getState('busy')
}

request (endpoint, defaults) {
request (endpoint, defaults, withResponse) {
const _endpoint =
typeof defaults === 'object'
? Object.assign({}, defaults, endpoint)
: endpoint

if (!this.ctx.app.$axios) {
// eslint-disable-next-line no-console
console.error('[AUTH] add the @nuxtjs/axios module to nuxt.config file')
return
}

return this.ctx.app.$axios
.request(_endpoint)
.then(response => {
if (_endpoint.propertyName) {
return getProp(response.data, _endpoint.propertyName)
const result = _endpoint.propertyName ? getProp(response.data, _endpoint.propertyName) : response.data

if (withResponse) {
return {
response,
result
}
} else {
return response.data
return result
}
})
.catch(error => {
Expand All @@ -285,7 +295,7 @@ export default class Auth {
})
}

requestWith (strategy, endpoint, defaults) {
requestWith (strategy, endpoint, defaults, withResponse) {
const token = this.getToken(strategy)

const _endpoint = Object.assign({}, defaults, endpoint)
Expand All @@ -298,16 +308,17 @@ export default class Auth {
_endpoint.headers[tokenName] = token
}

return this.request(_endpoint)
return this.request(_endpoint, false, withResponse)
}

wrapLogin (promise) {
this.$storage.setState('busy', true)
this.error = null

return Promise.resolve(promise)
.then(() => {
.then(response => {
this.$storage.setState('busy', false)
return response
})
.catch(error => {
this.$storage.setState('busy', false)
Expand Down Expand Up @@ -389,7 +400,7 @@ export default class Auth {
const userScopes = this.$state.user && getProp(this.$state.user, this.options.scopeKey)

if (!userScopes) {
return undefined
return false
}

if (Array.isArray(userScopes)) {
Expand Down
3 changes: 1 addition & 2 deletions lib/core/storage.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import Vue from 'vue'
import getProp from 'dotprop'
import { parse as parseCookie, serialize as serializeCookie } from 'cookie'
import { isUnset, isSet, decodeValue, encodeValue } from './utilities'
import { isUnset, isSet, decodeValue, encodeValue, getProp } from './utilities'

export default class Storage {
constructor (ctx, options) {
Expand Down
31 changes: 29 additions & 2 deletions lib/core/utilities.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
export const isUnset = o => typeof o === 'undefined' || o === null
export const isSet = o => !isUnset(o)

export const isSameURL = (a, b) => a.split('?')[0] === b.split('?')[0]
export const isSameURL = (a, b) => a.split('?')[0].replace(/\/+$/, '') === b.split('?')[0].replace(/\/+$/, '')

export const isRelativeURL = u =>
u && u.length && /^\/[a-zA-Z0-9@\-%_~][/a-zA-Z0-9@\-%_~]*[?]?([^#]*)#?([^#]*)$/.test(u)
u && u.length && /^\/([a-zA-Z0-9@\-%_~][/a-zA-Z0-9@\-%_~]*)?([?][^#]*)?(#[^#]*)?$/.test(u)

export const parseQuery = queryString => {
const query = {}
Expand Down Expand Up @@ -83,3 +83,30 @@ export function decodeValue (val) {
// Return as is
return val
}

/**
* Get property defined by dot notation in string.
* Based on https://github.com/dy/dotprop (MIT)
*
* @param {Object} holder Target object where to look property up
* @param {string} propName Dot notation, like 'this.a.b.c'
* @return {*} A property value
*/
export function getProp (holder, propName) {
if (!propName || !holder) {
return holder
}

if (propName in holder) {
return holder[propName]
}

const propParts = Array.isArray(propName) ? propName : (propName + '').split('.')

let result = holder
while (propParts.length && result) {
result = result[propParts.shift()]
}

return result
}
5 changes: 4 additions & 1 deletion lib/module/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ module.exports = function (moduleOptions) {

// Copy plugin
copyPlugin.call(this, { options, strategies, strategyScheme })

// Transpile nanoid (used for oauth2) for IE11 support (#472)
this.options.build.transpile.push(/^nanoid/)
}

function validateOptions (options) {
Expand All @@ -48,7 +51,7 @@ function validateOptions (options) {
}

// Enforce vuex store because auth depends on it
if (!this.options.store) {
if (options.vuex && !this.options.store) {
logger.fatal('Enable vuex store by creating `store/index.js`.')
}
}
Expand Down
44 changes: 24 additions & 20 deletions lib/schemes/local.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,12 @@ export default class LocalScheme {
}

// Ditch any leftover local tokens before attempting to log in
await this._logoutLocally()
await this.$auth.reset()

const result = await this.$auth.request(
const { response, result } = await this.$auth.request(
endpoint,
this.options.endpoints.login
this.options.endpoints.login,
true
)

if (this.options.tokenRequired) {
Expand All @@ -51,21 +52,19 @@ export default class LocalScheme {
this._setToken(token)
}

return this.fetchUser()
if (this.options.autoFetchUser) {
await this.fetchUser()
}

return response
}

async setUserToken (tokenValue) {
// Ditch any leftover local tokens before attempting to log in
await this._logoutLocally()

if (this.options.tokenRequired) {
const token = this.options.tokenType
? this.options.tokenType + ' ' + tokenValue
: tokenValue

this.$auth.setToken(this.name, token)
this._setToken(token)
}
const token = this.options.tokenType
? this.options.tokenType + ' ' + tokenValue
: tokenValue
this.$auth.setToken(this.name, token)
this._setToken(token)

return this.fetchUser()
}
Expand Down Expand Up @@ -99,22 +98,27 @@ export default class LocalScheme {
.catch(() => { })
}

// But logout locally regardless
return this._logoutLocally()
// But reset regardless
return this.$auth.reset()
}

async _logoutLocally () {
async reset () {
if (this.options.tokenRequired) {
this._clearToken()
}

return this.$auth.reset()
this.$auth.setUser(false)
this.$auth.setToken(this.name, false)
this.$auth.setRefreshToken(this.name, false)

return Promise.resolve()
}
}

const DEFAULTS = {
tokenRequired: true,
tokenType: 'Bearer',
globalToken: true,
tokenName: 'Authorization'
tokenName: 'Authorization',
autoFetchUser: true
}
9 changes: 7 additions & 2 deletions lib/schemes/oauth2.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,14 @@ export default class Oauth2Scheme {
this.$auth.ctx.app.$axios.setHeader(this.options.tokenName, false)
}

async logout () {
async reset () {
this._clearToken()
return this.$auth.reset()

this.$auth.setUser(false)
this.$auth.setToken(this.name, false)
this.$auth.setRefreshToken(this.name, false)

return Promise.resolve()
}

login ({ params, state, nonce } = {}) {
Expand Down
Loading

0 comments on commit 56c247c

Please sign in to comment.