Launch Week Day 3: Introducing Organization Notifications in Socket.Learn More
Socket
Book a DemoSign in
Socket

@nuxtjs/auth

Package Overview
Dependencies
Maintainers
4
Versions
51
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@nuxtjs/auth - npm Package Compare versions

Comparing version
4.0.0
to
4.0.1
+336
lib/core/auth.js
import getProp from 'dotprop'
import Storage from './storage'
import { routeOption, isRelativeURL, isSet, isSameURL } from './utilities'
export default class Auth {
constructor (ctx, options) {
this.ctx = ctx
this.options = options
// Strategies
this.strategies = {}
// Error listeners
this._errorListeners = []
// Storage & State
options.initialState = { user: null, loggedIn: false }
const storage = new Storage(ctx, options)
this.$storage = storage
this.$state = storage.state
}
init () {
// Watch for loggedIn changes only in client side
if (process.browser) {
this.$storage.watchState('loggedIn', loggedIn => {
if (!routeOption(this.ctx.route, 'auth', false)) {
this.redirect(loggedIn ? 'home' : 'logout')
}
})
}
// Restore strategy
this.$storage.syncUniversal('strategy', this.options.defaultStrategy)
// Set default strategy if current one is invalid
if (!this.strategy) {
this.$storage.setUniversal('strategy', this.options.defaultStrategy)
// Give up if still invalid
if (!this.strategy) {
return Promise.resolve()
}
}
// Call mounted for active strategy on initial load
return this.mounted()
}
// Backward compatibility
get state () {
if (!this._state_warn_shown) {
this._state_warn_shown = true
// eslint-disable-next-line no-console
console.warn('[AUTH] $auth.state is deprecated. Please use $auth.$state or top level props like $auth.loggedIn')
}
return this.$state
}
getState (key) {
if (!this._get_state_warn_shown) {
this._get_state_warn_shown = true
// eslint-disable-next-line no-console
console.warn('[AUTH] $auth.getState is deprecated. Please use $auth.$storage.getState() or top level props like $auth.loggedIn')
}
return this.$storage.getState(key)
}
// ---------------------------------------------------------------
// Strategy and Scheme
// ---------------------------------------------------------------
get strategy () {
return this.strategies[this.$state.strategy]
}
registerStrategy (name, strategy) {
this.strategies[name] = strategy
}
setStrategy (name) {
if (name === this.$storage.getUniversal('strategy')) {
return Promise.resolve()
}
// Set strategy
this.$storage.setUniversal('strategy', name)
// Call mounted hook on active strategy
return this.mounted()
}
mounted () {
if (!this.strategy.mounted) {
return this.fetchUserOnce()
}
return Promise.resolve(this.strategy.mounted(...arguments)).catch(error => {
this.callOnError(error, { method: 'mounted' })
return Promise.reject(error)
})
}
loginWith (name, ...args) {
return this.setStrategy(name).then(() => this.login(...args))
}
login () {
if (!this.strategy.login) {
return Promise.resolve()
}
return this.wrapLogin(this.strategy.login(...arguments)).catch(error => {
this.callOnError(error, { method: 'login' })
return Promise.reject(error)
})
}
fetchUser () {
if (!this.strategy.fetchUser) {
return Promise.resolve()
}
return Promise.resolve(this.strategy.fetchUser(...arguments)).catch(error => {
this.callOnError(error, { method: 'fetchUser' })
return Promise.reject(error)
})
}
logout () {
if (!this.strategy.logout) {
this.reset()
return Promise.resolve()
}
return Promise.resolve(this.strategy.logout(...arguments)).catch(error => {
this.callOnError(error, { method: 'logout' })
return Promise.reject(error)
})
}
reset () {
if (!this.strategy.reset) {
this.setUser(null)
this.setToken(this.$state.strategy, null)
return Promise.resolve()
}
return Promise.resolve(this.strategy.reset(...arguments)).catch(error => {
this.callOnError(error, { method: 'reset' })
return Promise.reject(error)
})
}
// ---------------------------------------------------------------
// Token helpers
// ---------------------------------------------------------------
getToken (strategy) {
const _key = this.options.token.prefix + strategy
return this.$storage.getUniversal(_key)
}
setToken (strategy, token) {
const _key = this.options.token.prefix + strategy
return this.$storage.setUniversal(_key, token)
}
syncToken (strategy) {
const _key = this.options.token.prefix + strategy
return this.$storage.syncUniversal(_key)
}
// ---------------------------------------------------------------
// User helpers
// ---------------------------------------------------------------
get user () {
return this.$state.user
}
get loggedIn () {
return this.$state.loggedIn
}
fetchUserOnce () {
if (!this.$state.user) {
return this.fetchUser(...arguments)
}
return Promise.resolve()
}
setUser (user) {
this.$storage.setState('loggedIn', Boolean(user))
this.$storage.setState('user', user)
}
// ---------------------------------------------------------------
// Utils
// ---------------------------------------------------------------
get busy () {
return this.$storage.getState('busy')
}
request (endpoint, defaults) {
const _endpoint =
typeof defaults === 'object'
? Object.assign({}, defaults, endpoint)
: endpoint
return this.ctx.app.$axios
.request(_endpoint)
.then(response => {
if (_endpoint.propertyName) {
return getProp(response.data, _endpoint.propertyName)
} else {
return response.data
}
})
.catch(error => {
// Call all error handlers
this.callOnError(error, { method: 'request' })
// Throw error
return Promise.reject(error)
})
}
requestWith (strategy, endpoint, defaults) {
const token = this.getToken(strategy)
const _endpoint = Object.assign({}, defaults, endpoint)
if (!_endpoint.headers) {
_endpoint.headers = {}
}
if (!_endpoint.headers['Authorization'] && isSet(token)) {
_endpoint.headers['Authorization'] = token
}
return this.request(_endpoint)
}
wrapLogin (promise) {
this.$storage.setState('busy', true)
this.error = null
return Promise.resolve(promise)
.then(() => {
this.$storage.setState('busy', false)
})
.catch(error => {
this.$storage.setState('busy', false)
return Promise.reject(error)
})
}
onError (listener) {
this._errorListeners.push(listener)
}
callOnError (error, payload = {}) {
this.error = error
for (let fn of this._errorListeners) {
fn(error, payload)
}
}
redirect (name, noRouter = false) {
if (!this.options.redirect) {
return
}
const from = this.options.fullPathRedirect ? this.ctx.route.path : this.ctx.route.fullPath
let to = this.options.redirect[name]
if (!to) {
return
}
// Apply rewrites
if (this.options.rewriteRedirects) {
if (name === 'login' && isRelativeURL(from) && !isSameURL(to, from)) {
this.$storage.setUniversal('redirect', from)
}
if (name === 'home') {
const redirect = this.$storage.getUniversal('redirect')
this.$storage.setUniversal('redirect', null)
if (isRelativeURL(redirect)) {
to = redirect
}
}
}
// Prevent infinity redirects
if (isSameURL(to, from)) {
return
}
if (process.browser) {
if (noRouter) {
window.location.replace(to)
} else {
this.ctx.redirect(to)
}
} else {
this.ctx.redirect(to)
}
}
hasScope (scope) {
const userScopes = this.$state.user && getProp(this.$state.user, this.options.scopeKey)
if (!userScopes) {
return undefined
}
if (Array.isArray(userScopes)) {
return userScopes.includes(scope)
}
return Boolean(getProp(userScopes, scope))
}
}
import Middleware from '../middleware'
import { routeOption } from './utilities'
Middleware.auth = function (ctx) {
// Disable middleware if options: { auth: false } is set on the route
if (routeOption(ctx.route, 'auth', false)) {
return
}
const { login } = ctx.app.$auth.options.redirect
if (ctx.app.$auth.$state.loggedIn) {
// -- Authorized --
// Redirect to home page if inside login page
if (login && ctx.route.path === login.split('?')[0]) {
ctx.app.$auth.redirect('home')
}
} else {
// -- Guest --
// Redirect to login path if not authorized
ctx.app.$auth.redirect('login')
}
}
import Vue from 'vue'
import Cookies from 'js-cookie'
import getProp from 'dotprop'
import { parse as parseCookie } from 'cookie'
import { isUnset, isSet } from './utilities'
export default class Storage {
constructor (ctx, options) {
this.ctx = ctx
this.options = options
this._initState()
}
// ------------------------------------
// Universal
// ------------------------------------
setUniversal (key, value, isJson) {
// Local state
this.setState(key, value)
// Cookies
this.setCookie(key, value)
// Local Storage
this.setLocalStorage(key, value, isJson)
return value
}
getUniversal (key, isJson) {
// Local state
let value = this.getState(key)
// Cookies
if (isUnset(value)) {
value = this.getCookie(key, isJson)
}
// Local Storage
if (isUnset(value)) {
value = this.getLocalStorage(key, isJson)
}
return value
}
syncUniversal (key, defaultValue, isJson) {
let value = this.getUniversal(key, isJson)
if (isUnset(value) && isSet(defaultValue)) {
value = defaultValue
}
if (isSet(value)) {
this.setUniversal(key, value)
}
return value
}
// ------------------------------------
// Local state (reactive)
// ------------------------------------
_initState () {
// Private state is suitable to keep information not being exposed to Vuex store
// This helps prevent stealing token from SSR response HTML
Vue.set(this, '_state', {})
// Use vuex for local state's if possible
this._useVuex = this.options.vuex && this.ctx.store
if (this._useVuex) {
const storeModule = {
namespaced: true,
state: () => this.options.initialState,
mutations: {
SET (state, payload) {
Vue.set(state, payload.key, payload.value)
}
}
}
this.ctx.store.registerModule(this.options.vuex.namespace, storeModule, {
preserveState: Boolean(this.ctx.store.state[this.options.vuex.namespace])
})
this.state = this.ctx.store.state[this.options.vuex.namespace]
} else {
Vue.set(this, 'state', {})
}
}
setState (key, value) {
if (key[0] === '_') {
Vue.set(this._state, key, value)
} else {
if (this._useVuex) {
this.ctx.store.commit(this.options.vuex.namespace + '/SET', {
key,
value
})
} else {
Vue.set(this.state, key, value)
}
}
return value
}
getState (key) {
if (key[0] !== '_') {
return this.state[key]
} else {
return this._state[key]
}
}
watchState (key, fn) {
if (this._useVuex) {
return this.ctx.store.watch(
state => getProp(state[this.options.vuex.namespace], key),
fn
)
}
}
// ------------------------------------
// Local storage
// ------------------------------------
setLocalStorage (key, value, isJson) {
if (typeof localStorage === 'undefined' || !this.options.localStorage) {
return
}
const _key = this.options.localStorage.prefix + key
if (isUnset(value)) {
localStorage.removeItem(_key)
} else {
localStorage.setItem(_key, isJson ? JSON.stringify(value) : value)
}
return value
}
getLocalStorage (key, isJson) {
if (typeof localStorage === 'undefined' || !this.options.localStorage) {
return
}
const _key = this.options.localStorage.prefix + key
const value = localStorage.getItem(_key)
return isJson ? JSON.parse(value) : value
}
// ------------------------------------
// Cookies
// ------------------------------------
setCookie (key, value, options = {}) {
if (process.server || !this.options.cookie) {
return
}
const _key = this.options.cookie.prefix + key
const _options = Object.assign({}, this.options.cookie.options, options)
if (isUnset(value)) {
Cookies.remove(_key, _options)
} else {
Cookies.set(_key, value, _options)
}
return value
}
getCookie (key, isJson) {
if (!this.options.cookie) {
return
}
const _key = this.options.cookie.prefix + key
const cookieStr = process.browser
? document.cookie
: this.ctx.req.headers.cookie
const cookies = parseCookie(cookieStr || '') || {}
const value = cookies[_key]
return isJson ? JSON.parse(value) : value
}
}
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 isRelativeURL = u =>
u && u.length && /^\/[a-zA-Z0-9@\-%_~][/a-zA-Z0-9@\-%_~]{1,200}$/.test(u)
export const parseQuery = queryString => {
const query = {}
const pairs = queryString.split('&')
for (let i = 0; i < pairs.length; i++) {
const pair = pairs[i].split('=')
query[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1] || '')
}
return query
}
export const encodeQuery = queryObject => {
return Object.keys(queryObject)
.map(
key =>
encodeURIComponent(key) + '=' + encodeURIComponent(queryObject[key])
)
.join('&')
}
export const randomString = () => btoa(Math.random() + '').replace('==', '')
export const routeOption = (route, key, value) => {
return route.matched.some(m => {
if (process.browser) {
// Browser
return Object.values(m.components).some(
component => component.options[key] === value
)
} else {
// SSR
return Object.values(m.components).some(component =>
Object.values(component._Ctor).some(
ctor => ctor.options && ctor.options[key] === value
)
)
}
})
}
+13
-0

@@ -5,2 +5,15 @@ # Change Log

<a name="4.0.1"></a>
## [4.0.1](https://github.com/nuxt-community/auth-module/compare/v4.0.0...v4.0.1) (2018-04-03)
### Bug Fixes
* **local-scheme-token:** avoid token type duplicata on Axios requests ([3908563](https://github.com/nuxt-community/auth-module/commit/3908563))
* **local-scheme-token:** removed token type from axios setToken ([c64e7f1](https://github.com/nuxt-community/auth-module/commit/c64e7f1)), closes [#113](https://github.com/nuxt-community/auth-module/issues/113)
* **scheme-resolution:** fix problem with backslashes in path to schemes on windows ([77161b8](https://github.com/nuxt-community/auth-module/commit/77161b8))
* no token exception when tokenRequired is set to false ([#118](https://github.com/nuxt-community/auth-module/issues/118)) ([56265a7](https://github.com/nuxt-community/auth-module/commit/56265a7))
<a name="4.0.0"></a>

@@ -7,0 +20,0 @@ # [4.0.0](https://github.com/nuxt-community/auth-module/compare/v4.0.0-rc.3...v4.0.0) (2018-04-02)

+1
-1

@@ -63,3 +63,3 @@ const { resolve, join, basename } = require('path')

function copyCore (options) {
const coreRoot = resolve(libRoot, 'auth')
const coreRoot = resolve(libRoot, 'core')

@@ -66,0 +66,0 @@ for (const file of readdirSync(coreRoot)) {

@@ -6,3 +6,3 @@ import Auth from './auth'

// Active chemes
<%= options.uniqueSchemes.map(path =>`import ${'scheme_' + hash(path)} from '${path}'`).join('\n') %>
<%= options.uniqueSchemes.map(path =>`import ${'scheme_' + hash(path)} from '${path.replace(/\\/g,'/')}'`).join('\n') %>

@@ -9,0 +9,0 @@ export default function (ctx, inject) {

@@ -12,3 +12,3 @@ export default class LocalScheme {

// Set Authorization token for all axios requests
this.$auth.ctx.app.$axios.setToken(token, this.options.tokenType)
this.$auth.ctx.app.$axios.setToken(token)
}

@@ -15,0 +15,0 @@ }

{
"name": "@nuxtjs/auth",
"version": "4.0.0",
"version": "4.0.1",
"description": "Authentication module for Nuxt.js",

@@ -5,0 +5,0 @@ "license": "MIT",

@@ -1,6 +0,4 @@

# 🔑 Auth Module
<h1 align="center" >🔑 Auth Module</h1>
<p align="center">Authentication module for Nuxt.js</p>
> Authentication module for Nuxt.js
<p align="center">

@@ -28,6 +26,11 @@ <a href="https://david-dm.org/nuxt-community/auth-module">

📖 [**Read Documentation**](https://auth.nuxtjs.org)
<p align="center">
<a href="https://auth.nuxtjs.org">Read Documentation</a>
</p>
**Running demo for development:**
## Development
Running demo for development:
```bash

@@ -38,4 +41,4 @@ $ yarn install

## 📑 License
## License
[MIT License](./LICENSE) - Copyright (c) Nuxt Community
import getProp from 'dotprop'
import Storage from './storage'
import { routeOption, isRelativeURL, isUnset, isSameURL } from './utilities'
export default class Auth {
constructor (ctx, options) {
this.ctx = ctx
this.options = options
// Strategies
this.strategies = {}
// Error listeners
this._errorListeners = []
// Storage & State
options.initialState = { user: null, loggedIn: false }
const storage = new Storage(ctx, options)
this.$storage = storage
this.$state = storage.state
}
init () {
// Watch for loggedIn changes only in client side
if (process.browser) {
this.$storage.watchState('loggedIn', loggedIn => {
if (!routeOption(this.ctx.route, 'auth', false)) {
this.redirect(loggedIn ? 'home' : 'logout')
}
})
}
// Restore strategy
this.$storage.syncUniversal('strategy', this.options.defaultStrategy)
// Set default strategy if current one is invalid
if (!this.strategy) {
this.$storage.setUniversal('strategy', this.options.defaultStrategy)
// Give up if still invalid
if (!this.strategy) {
return Promise.resolve()
}
}
// Call mounted for active strategy on initial load
return this.mounted()
}
// Backward compatibility
get state () {
if (!this._state_warn_shown) {
this._state_warn_shown = true
// eslint-disable-next-line no-console
console.warn('[AUTH] $auth.state is deprecated. Please use $auth.$state or top level props like $auth.loggedIn')
}
return this.$state
}
getState (key) {
if (!this._get_state_warn_shown) {
this._get_state_warn_shown = true
// eslint-disable-next-line no-console
console.warn('[AUTH] $auth.getState is deprecated. Please use $auth.$storage.getState() or top level props like $auth.loggedIn')
}
return this.$storage.getState(key)
}
// ---------------------------------------------------------------
// Strategy and Scheme
// ---------------------------------------------------------------
get strategy () {
return this.strategies[this.$state.strategy]
}
registerStrategy (name, strategy) {
this.strategies[name] = strategy
}
setStrategy (name) {
if (name === this.$storage.getUniversal('strategy')) {
return Promise.resolve()
}
// Set strategy
this.$storage.setUniversal('strategy', name)
// Call mounted hook on active strategy
return this.mounted()
}
mounted () {
if (!this.strategy.mounted) {
return this.fetchUserOnce()
}
return Promise.resolve(this.strategy.mounted(...arguments)).catch(error => {
this.callOnError(error, { method: 'mounted' })
return Promise.reject(error)
})
}
loginWith (name, ...args) {
return this.setStrategy(name).then(() => this.login(...args))
}
login () {
if (!this.strategy.login) {
return Promise.resolve()
}
return this.wrapLogin(this.strategy.login(...arguments)).catch(error => {
this.callOnError(error, { method: 'login' })
return Promise.reject(error)
})
}
fetchUser () {
if (!this.strategy.fetchUser) {
return Promise.resolve()
}
return Promise.resolve(this.strategy.fetchUser(...arguments)).catch(error => {
this.callOnError(error, { method: 'fetchUser' })
return Promise.reject(error)
})
}
logout () {
if (!this.strategy.logout) {
this.reset()
return Promise.resolve()
}
return Promise.resolve(this.strategy.logout(...arguments)).catch(error => {
this.callOnError(error, { method: 'logout' })
return Promise.reject(error)
})
}
reset () {
if (!this.strategy.reset) {
this.setUser(null)
this.setToken(this.$state.strategy, null)
return Promise.resolve()
}
return Promise.resolve(this.strategy.reset(...arguments)).catch(error => {
this.callOnError(error, { method: 'reset' })
return Promise.reject(error)
})
}
// ---------------------------------------------------------------
// Token helpers
// ---------------------------------------------------------------
getToken (strategy) {
const _key = this.options.token.prefix + strategy
return this.$storage.getUniversal(_key)
}
setToken (strategy, token) {
const _key = this.options.token.prefix + strategy
return this.$storage.setUniversal(_key, token)
}
syncToken (strategy) {
const _key = this.options.token.prefix + strategy
return this.$storage.syncUniversal(_key)
}
// ---------------------------------------------------------------
// User helpers
// ---------------------------------------------------------------
get user () {
return this.$state.user
}
get loggedIn () {
return this.$state.loggedIn
}
fetchUserOnce () {
if (!this.$state.user) {
return this.fetchUser(...arguments)
}
return Promise.resolve()
}
setUser (user) {
this.$storage.setState('loggedIn', Boolean(user))
this.$storage.setState('user', user)
}
// ---------------------------------------------------------------
// Utils
// ---------------------------------------------------------------
get busy () {
return this.$storage.getState('busy')
}
request (endpoint, defaults) {
const _endpoint =
typeof defaults === 'object'
? Object.assign({}, defaults, endpoint)
: endpoint
return this.ctx.app.$axios
.request(_endpoint)
.then(response => {
if (_endpoint.propertyName) {
return getProp(response.data, _endpoint.propertyName)
} else {
return response.data
}
})
.catch(error => {
// Call all error handlers
this.callOnError(error, { method: 'request' })
// Throw error
return Promise.reject(error)
})
}
requestWith (strategy, endpoint, defaults) {
const token = this.getToken(strategy)
if (isUnset(token)) {
return Promise.reject(new Error('No Token'))
}
const _endpoint = Object.assign({}, defaults, endpoint)
if (!_endpoint.headers) {
_endpoint.headers = {}
}
if (!_endpoint.headers['Authorization']) {
_endpoint.headers['Authorization'] = token
}
return this.request(_endpoint)
}
wrapLogin (promise) {
this.$storage.setState('busy', true)
this.error = null
return Promise.resolve(promise)
.then(() => {
this.$storage.setState('busy', false)
})
.catch(error => {
this.$storage.setState('busy', false)
return Promise.reject(error)
})
}
onError (listener) {
this._errorListeners.push(listener)
}
callOnError (error, payload = {}) {
this.error = error
for (let fn of this._errorListeners) {
fn(error, payload)
}
}
redirect (name, noRouter = false) {
if (!this.options.redirect) {
return
}
const from = this.options.fullPathRedirect ? this.ctx.route.path : this.ctx.route.fullPath
let to = this.options.redirect[name]
if (!to) {
return
}
// Apply rewrites
if (this.options.rewriteRedirects) {
if (name === 'login' && isRelativeURL(from) && !isSameURL(to, from)) {
this.$storage.setUniversal('redirect', from)
}
if (name === 'home') {
const redirect = this.$storage.getUniversal('redirect')
this.$storage.setUniversal('redirect', null)
if (isRelativeURL(redirect)) {
to = redirect
}
}
}
// Prevent infinity redirects
if (isSameURL(to, from)) {
return
}
if (process.browser) {
if (noRouter) {
window.location.replace(to)
} else {
this.ctx.redirect(to)
}
} else {
this.ctx.redirect(to)
}
}
hasScope (scope) {
const userScopes = this.$state.user && getProp(this.$state.user, this.options.scopeKey)
if (!userScopes) {
return undefined
}
if (Array.isArray(userScopes)) {
return userScopes.includes(scope)
}
return Boolean(getProp(userScopes, scope))
}
}
import Middleware from '../middleware'
import { routeOption } from './utilities'
Middleware.auth = function (ctx) {
// Disable middleware if options: { auth: false } is set on the route
if (routeOption(ctx.route, 'auth', false)) {
return
}
const { login } = ctx.app.$auth.options.redirect
if (ctx.app.$auth.$state.loggedIn) {
// -- Authorized --
// Redirect to home page if inside login page
if (login && ctx.route.path === login.split('?')[0]) {
ctx.app.$auth.redirect('home')
}
} else {
// -- Guest --
// Redirect to login path if not authorized
ctx.app.$auth.redirect('login')
}
}
import Vue from 'vue'
import Cookies from 'js-cookie'
import getProp from 'dotprop'
import { parse as parseCookie } from 'cookie'
import { isUnset, isSet } from './utilities'
export default class Storage {
constructor (ctx, options) {
this.ctx = ctx
this.options = options
this._initState()
}
// ------------------------------------
// Universal
// ------------------------------------
setUniversal (key, value, isJson) {
// Local state
this.setState(key, value)
// Cookies
this.setCookie(key, value)
// Local Storage
this.setLocalStorage(key, value, isJson)
return value
}
getUniversal (key, isJson) {
// Local state
let value = this.getState(key)
// Cookies
if (isUnset(value)) {
value = this.getCookie(key, isJson)
}
// Local Storage
if (isUnset(value)) {
value = this.getLocalStorage(key, isJson)
}
return value
}
syncUniversal (key, defaultValue, isJson) {
let value = this.getUniversal(key, isJson)
if (isUnset(value) && isSet(defaultValue)) {
value = defaultValue
}
if (isSet(value)) {
this.setUniversal(key, value)
}
return value
}
// ------------------------------------
// Local state (reactive)
// ------------------------------------
_initState () {
// Private state is suitable to keep information not being exposed to Vuex store
// This helps prevent stealing token from SSR response HTML
Vue.set(this, '_state', {})
// Use vuex for local state's if possible
this._useVuex = this.options.vuex && this.ctx.store
if (this._useVuex) {
const storeModule = {
namespaced: true,
state: () => this.options.initialState,
mutations: {
SET (state, payload) {
Vue.set(state, payload.key, payload.value)
}
}
}
this.ctx.store.registerModule(this.options.vuex.namespace, storeModule, {
preserveState: Boolean(this.ctx.store.state[this.options.vuex.namespace])
})
this.state = this.ctx.store.state[this.options.vuex.namespace]
} else {
Vue.set(this, 'state', {})
}
}
setState (key, value) {
if (key[0] === '_') {
Vue.set(this._state, key, value)
} else {
if (this._useVuex) {
this.ctx.store.commit(this.options.vuex.namespace + '/SET', {
key,
value
})
} else {
Vue.set(this.state, key, value)
}
}
return value
}
getState (key) {
if (key[0] !== '_') {
return this.state[key]
} else {
return this._state[key]
}
}
watchState (key, fn) {
if (this._useVuex) {
return this.ctx.store.watch(
state => getProp(state[this.options.vuex.namespace], key),
fn
)
}
}
// ------------------------------------
// Local storage
// ------------------------------------
setLocalStorage (key, value, isJson) {
if (typeof localStorage === 'undefined' || !this.options.localStorage) {
return
}
const _key = this.options.localStorage.prefix + key
if (isUnset(value)) {
localStorage.removeItem(_key)
} else {
localStorage.setItem(_key, isJson ? JSON.stringify(value) : value)
}
return value
}
getLocalStorage (key, isJson) {
if (typeof localStorage === 'undefined' || !this.options.localStorage) {
return
}
const _key = this.options.localStorage.prefix + key
const value = localStorage.getItem(_key)
return isJson ? JSON.parse(value) : value
}
// ------------------------------------
// Cookies
// ------------------------------------
setCookie (key, value, options = {}) {
if (process.server || !this.options.cookie) {
return
}
const _key = this.options.cookie.prefix + key
const _options = Object.assign({}, this.options.cookie.options, options)
if (isUnset(value)) {
Cookies.remove(_key, _options)
} else {
Cookies.set(_key, value, _options)
}
return value
}
getCookie (key, isJson) {
if (!this.options.cookie) {
return
}
const _key = this.options.cookie.prefix + key
const cookieStr = process.browser
? document.cookie
: this.ctx.req.headers.cookie
const cookies = parseCookie(cookieStr || '') || {}
const value = cookies[_key]
return isJson ? JSON.parse(value) : value
}
}
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 isRelativeURL = u =>
u && u.length && /^\/[a-zA-Z0-9@\-%_~][/a-zA-Z0-9@\-%_~]{1,200}$/.test(u)
export const parseQuery = queryString => {
const query = {}
const pairs = queryString.split('&')
for (let i = 0; i < pairs.length; i++) {
const pair = pairs[i].split('=')
query[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1] || '')
}
return query
}
export const encodeQuery = queryObject => {
return Object.keys(queryObject)
.map(
key =>
encodeURIComponent(key) + '=' + encodeURIComponent(queryObject[key])
)
.join('&')
}
export const randomString = () => btoa(Math.random() + '').replace('==', '')
export const routeOption = (route, key, value) => {
return route.matched.some(m => {
if (process.browser) {
// Browser
return Object.values(m.components).some(
component => component.options[key] === value
)
} else {
// SSR
return Object.values(m.components).some(component =>
Object.values(component._Ctor).some(
ctor => ctor.options && ctor.options[key] === value
)
)
}
})
}