feat: auth self-registration config + gql grouping
This commit is contained in:
1 parent
49834461a6
commit
0afa65fa58
39 files changed
+104
-50
No files matched your search
@@ -9,7 +9,8 @@
|
|||||||
|
|
||||||
v-tab-item(key='settings', :transition='false', :reverse-transition='false')
|
v-tab-item(key='settings', :transition='false', :reverse-transition='false')
|
||||||
v-card.pa-3(flat, tile)
|
v-card.pa-3(flat, tile)
|
||||||
v-subheader.pl-0.pb-2 Select which authentication strategies to enable:
|
.body-2.grey--text.text--darken-1 Select which authentication strategies to enable:
|
||||||
|
.caption.grey--text.pb-2 Some strategies require additional configuration in their dedicated tab (when selected).
|
||||||
v-form
|
v-form
|
||||||
v-checkbox(
|
v-checkbox(
|
||||||
v-for='strategy in strategies',
|
v-for='strategy in strategies',
|
||||||
@@ -27,19 +28,36 @@
|
|||||||
v-form
|
v-form
|
||||||
v-subheader.pl-0 Strategy Configuration
|
v-subheader.pl-0 Strategy Configuration
|
||||||
.body-1.ml-3(v-if='!strategy.config || strategy.config.length < 1') This strategy has no configuration options you can modify.
|
.body-1.ml-3(v-if='!strategy.config || strategy.config.length < 1') This strategy has no configuration options you can modify.
|
||||||
v-text-field(v-else, v-for='cfg in strategy.config', :key='cfg.key', :label='cfg.key', prepend-icon='settings_applications')
|
v-text-field(
|
||||||
|
v-else
|
||||||
|
v-for='cfg in strategy.config'
|
||||||
|
:key='cfg.key'
|
||||||
|
:label='cfg.key'
|
||||||
|
v-model='cfg.value'
|
||||||
|
prepend-icon='settings_applications'
|
||||||
|
)
|
||||||
v-divider
|
v-divider
|
||||||
v-subheader.pl-0 Registration
|
v-subheader.pl-0 Registration
|
||||||
v-switch.ml-3(
|
v-switch.ml-3(
|
||||||
v-model='auths',
|
v-model='allowSelfRegistration',
|
||||||
label='Allow self-registration',
|
label='Allow self-registration',
|
||||||
:value='true',
|
:value='true',
|
||||||
color='primary',
|
color='primary',
|
||||||
hint='Allow any user successfully authorized by the strategy to access the wiki.',
|
hint='Allow any user successfully authorized by the strategy to access the wiki.',
|
||||||
persistent-hint
|
persistent-hint
|
||||||
)
|
)
|
||||||
v-text-field.ml-3(label='Limit to specific email domains', prepend-icon='mail_outline')
|
v-text-field.ml-3(
|
||||||
v-text-field.ml-3(label='Assign to group', prepend-icon='people')
|
label='Limit to specific email domains'
|
||||||
|
prepend-icon='mail_outline'
|
||||||
|
hint='Domain(s) seperated by comma. (e.g. domain1.com, domain2.com)'
|
||||||
|
persistent-hint
|
||||||
|
)
|
||||||
|
v-text-field.ml-3(
|
||||||
|
label='Assign to group'
|
||||||
|
prepend-icon='people'
|
||||||
|
hint='Automatically assign new users to these groups.'
|
||||||
|
persistent-hint
|
||||||
|
)
|
||||||
|
|
||||||
v-card-chin
|
v-card-chin
|
||||||
v-btn(color='primary')
|
v-btn(color='primary')
|
||||||
@@ -54,14 +72,17 @@
|
|||||||
<script>
|
<script>
|
||||||
import _ from 'lodash'
|
import _ from 'lodash'
|
||||||
|
|
||||||
import strategiesQuery from 'gql/admin-auth-query-strategies.gql'
|
import strategiesQuery from 'gql/admin/auth/auth-query-strategies.gql'
|
||||||
import strategiesSaveMutation from 'gql/admin-auth-mutation-save-strategies.gql'
|
import strategiesSaveMutation from 'gql/admin/auth/auth-mutation-save-strategies.gql'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
strategies: [],
|
strategies: [],
|
||||||
selectedStrategies: ['local']
|
selectedStrategies: ['local'],
|
||||||
|
selfRegistration: false,
|
||||||
|
domainWhitelist: [],
|
||||||
|
autoEnrollGroups: []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
|||||||
@@ -114,11 +114,11 @@
|
|||||||
import Criterias from '../common/criterias.vue'
|
import Criterias from '../common/criterias.vue'
|
||||||
import UserSearch from '../common/user-search.vue'
|
import UserSearch from '../common/user-search.vue'
|
||||||
|
|
||||||
import groupQuery from 'gql/admin-groups-query-single.gql'
|
import groupQuery from 'gql/admin/groups/groups-query-single.gql'
|
||||||
import assignUserMutation from 'gql/admin-groups-mutation-assign.gql'
|
import assignUserMutation from 'gql/admin/groups/groups-mutation-assign.gql'
|
||||||
import deleteGroupMutation from 'gql/admin-groups-mutation-delete.gql'
|
import deleteGroupMutation from 'gql/admin/groups/groups-mutation-delete.gql'
|
||||||
import unassignUserMutation from 'gql/admin-groups-mutation-unassign.gql'
|
import unassignUserMutation from 'gql/admin/groups/groups-mutation-unassign.gql'
|
||||||
import updateGroupMutation from 'gql/admin-groups-mutation-update.gql'
|
import updateGroupMutation from 'gql/admin/groups/groups-mutation-update.gql'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
.dialog-header.is-short New Group
|
.dialog-header.is-short New Group
|
||||||
v-card-text
|
v-card-text
|
||||||
v-text-field(v-model='newGroupName', label='Group Name', autofocus, counter='255', @keyup.enter='createGroup')
|
v-text-field(v-model='newGroupName', label='Group Name', autofocus, counter='255', @keyup.enter='createGroup')
|
||||||
v-card-actions
|
v-card-chin
|
||||||
v-spacer
|
v-spacer
|
||||||
v-btn(flat, @click='newGroupDialog = false') Cancel
|
v-btn(flat, @click='newGroupDialog = false') Cancel
|
||||||
v-btn(color='primary', @click='createGroup') Create
|
v-btn(color='primary', @click='createGroup') Create
|
||||||
@@ -45,9 +45,9 @@
|
|||||||
<script>
|
<script>
|
||||||
import _ from 'lodash'
|
import _ from 'lodash'
|
||||||
|
|
||||||
import groupsQuery from 'gql/admin-groups-query-list.gql'
|
import groupsQuery from 'gql/admin/groups/groups-query-list.gql'
|
||||||
import createGroupMutation from 'gql/admin-groups-mutation-create.gql'
|
import createGroupMutation from 'gql/admin/groups/groups-mutation-create.gql'
|
||||||
import deleteGroupMutation from 'gql/admin-groups-mutation-delete.gql'
|
import deleteGroupMutation from 'gql/admin/groups/groups-mutation-delete.gql'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
|
|||||||
@@ -128,9 +128,9 @@ import _ from 'lodash'
|
|||||||
|
|
||||||
/* global WIKI */
|
/* global WIKI */
|
||||||
|
|
||||||
import localesQuery from 'gql/admin-locale-query-list.gql'
|
import localesQuery from 'gql/admin/locale/locale-query-list.gql'
|
||||||
import localesDownloadMutation from 'gql/admin-locale-mutation-download.gql'
|
import localesDownloadMutation from 'gql/admin/locale/locale-mutation-download.gql'
|
||||||
import localesSaveMutation from 'gql/admin-locale-mutation-save.gql'
|
import localesSaveMutation from 'gql/admin/locale/locale-mutation-save.gql'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ import IconCube from 'mdi/cube'
|
|||||||
import IconDatabase from 'mdi/database'
|
import IconDatabase from 'mdi/database'
|
||||||
import IconNodeJs from 'mdi/nodejs'
|
import IconNodeJs from 'mdi/nodejs'
|
||||||
|
|
||||||
import systemInfoQuery from 'gql/admin-system-query-info.gql'
|
import systemInfoQuery from 'gql/admin/system/system-query-info.gql'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
|
|||||||
@@ -50,7 +50,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import _ from 'lodash'
|
import _ from 'lodash'
|
||||||
|
|
||||||
import themeSaveMutation from 'gql/admin-theme-mutation-save.gql'
|
import themeSaveMutation from 'gql/admin/theme/theme-mutation-save.gql'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
|
|||||||
@@ -48,7 +48,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import _ from 'lodash'
|
import _ from 'lodash'
|
||||||
|
|
||||||
import searchUsersQuery from 'gql/common-users-query-search.gql'
|
import searchUsersQuery from 'gql/common/common-users-query-search.gql'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
filters: {
|
filters: {
|
||||||
|
|||||||
@@ -56,9 +56,9 @@
|
|||||||
import _ from 'lodash'
|
import _ from 'lodash'
|
||||||
import { mapState } from 'vuex'
|
import { mapState } from 'vuex'
|
||||||
|
|
||||||
import strategiesQuery from 'gql/login-query-strategies.gql'
|
import strategiesQuery from 'gql/login/login-query-strategies.gql'
|
||||||
import loginMutation from 'gql/login-mutation-login.gql'
|
import loginMutation from 'gql/login/login-mutation-login.gql'
|
||||||
import tfaMutation from 'gql/login-mutation-tfa.gql'
|
import tfaMutation from 'gql/login/login-mutation-tfa.gql'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
i18nOptions: { namespaces: 'auth' },
|
i18nOptions: { namespaces: 'auth' },
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template lang='pug'>
|
<template lang='pug'>
|
||||||
v-app.profile
|
v-app(:dark='darkMode').profile
|
||||||
nav-header
|
nav-header
|
||||||
v-navigation-drawer.pb-0(v-model='profileDrawerShown', app, fixed, clipped, left, permanent)
|
v-navigation-drawer.pb-0(v-model='profileDrawerShown', app, fixed, clipped, left, permanent)
|
||||||
v-list(dense)
|
v-list(dense)
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
transition(name='profile-router')
|
transition(name='profile-router')
|
||||||
router-view
|
router-view
|
||||||
|
|
||||||
v-footer.py-2.justify-center(app, absolute, color='grey lighten-3', inset, height='auto')
|
v-footer.py-2.justify-center(app, absolute, :color='darkMode ? "" : "grey lighten-3"', inset, height='auto')
|
||||||
.caption.grey--text.text--darken-1 Powered by Wiki.js
|
.caption.grey--text.text--darken-1 Powered by Wiki.js
|
||||||
|
|
||||||
v-snackbar(
|
v-snackbar(
|
||||||
@@ -41,7 +41,7 @@
|
|||||||
import VueRouter from 'vue-router'
|
import VueRouter from 'vue-router'
|
||||||
import { mapState } from 'vuex'
|
import { mapState } from 'vuex'
|
||||||
|
|
||||||
/* global WIKI */
|
/* global WIKI, siteConfig */
|
||||||
|
|
||||||
const router = new VueRouter({
|
const router = new VueRouter({
|
||||||
mode: 'history',
|
mode: 'history',
|
||||||
@@ -75,7 +75,8 @@ export default {
|
|||||||
notificationState: {
|
notificationState: {
|
||||||
get() { return this.notification.isActive },
|
get() { return this.notification.isActive },
|
||||||
set(newState) { this.$store.commit('updateNotificationState', newState) }
|
set(newState) { this.$store.commit('updateNotificationState', newState) }
|
||||||
}
|
},
|
||||||
|
darkMode() { return siteConfig.darkMode }
|
||||||
},
|
},
|
||||||
router
|
router
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,8 +18,7 @@
|
|||||||
v-divider
|
v-divider
|
||||||
v-subheader.pl-0 Timezone
|
v-subheader.pl-0 Timezone
|
||||||
v-select.grey.lighten-5(solo, flat)
|
v-select.grey.lighten-5(solo, flat)
|
||||||
v-divider.my-0
|
v-card-chin
|
||||||
v-card-actions.grey.lighten-4
|
|
||||||
v-spacer
|
v-spacer
|
||||||
v-btn(color='primary')
|
v-btn(color='primary')
|
||||||
v-icon(left) chevron_right
|
v-icon(left) chevron_right
|
||||||
@@ -32,8 +31,7 @@
|
|||||||
v-card-text
|
v-card-text
|
||||||
v-subheader.pl-0 Default Editor
|
v-subheader.pl-0 Default Editor
|
||||||
v-select.grey.lighten-5(solo, flat)
|
v-select.grey.lighten-5(solo, flat)
|
||||||
v-divider.my-0
|
v-card-chin
|
||||||
v-card-actions.grey.lighten-4
|
|
||||||
v-spacer
|
v-spacer
|
||||||
v-btn(color='primary')
|
v-btn(color='primary')
|
||||||
v-icon(left) chevron_right
|
v-icon(left) chevron_right
|
||||||
@@ -42,10 +40,14 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
/* global siteConfig */
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
return { }
|
return { }
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
darkMode() { return siteConfig.darkMode }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -17,8 +17,7 @@
|
|||||||
v-text-field(label='Name', :counter='255', v-model='name', prepend-icon='person')
|
v-text-field(label='Name', :counter='255', v-model='name', prepend-icon='person')
|
||||||
v-text-field(label='Job Title', :counter='255', prepend-icon='accessibility')
|
v-text-field(label='Job Title', :counter='255', prepend-icon='accessibility')
|
||||||
v-text-field(label='Location / Office', :counter='255', prepend-icon='location_on')
|
v-text-field(label='Location / Office', :counter='255', prepend-icon='location_on')
|
||||||
v-divider.my-0
|
v-card-chin
|
||||||
v-card-actions.grey.lighten-4
|
|
||||||
v-spacer
|
v-spacer
|
||||||
v-btn(color='primary')
|
v-btn(color='primary')
|
||||||
v-icon(left) chevron_right
|
v-icon(left) chevron_right
|
||||||
@@ -29,8 +28,13 @@
|
|||||||
.subheading Authentication
|
.subheading Authentication
|
||||||
v-card-text
|
v-card-text
|
||||||
v-subheader.pl-0 Provider
|
v-subheader.pl-0 Provider
|
||||||
v-toolbar(flat, color='purple lighten-5', dense).purple--text.text--darken-4
|
v-toolbar(
|
||||||
v-icon(color='purple darken-4') supervised_user_circle
|
flat
|
||||||
|
:color='darkMode ? "grey darken-2" : "purple lighten-5"'
|
||||||
|
dense
|
||||||
|
:class='darkMode ? "grey--text text--lighten-1" : "purple--text text--darken-4"'
|
||||||
|
)
|
||||||
|
v-icon(:color='darkMode ? "grey lighten-1" : "purple darken-4"') supervised_user_circle
|
||||||
.subheading.ml-3 Local
|
.subheading.ml-3 Local
|
||||||
v-divider
|
v-divider
|
||||||
v-subheader.pl-0 Two-Factor Authentication (2FA)
|
v-subheader.pl-0 Two-Factor Authentication (2FA)
|
||||||
@@ -72,12 +76,16 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
/* global siteConfig */
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
name: 'John Doe'
|
name: 'John Doe'
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
darkMode() { return siteConfig.darkMode }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
File renamed without changes.
+4
-1
@@ -1,6 +1,6 @@
|
|||||||
query {
|
query {
|
||||||
authentication {
|
authentication {
|
||||||
strategies {
|
strategies(orderBy: "title ASC") {
|
||||||
isEnabled
|
isEnabled
|
||||||
key
|
key
|
||||||
props
|
props
|
||||||
@@ -10,6 +10,9 @@ query {
|
|||||||
key
|
key
|
||||||
value
|
value
|
||||||
}
|
}
|
||||||
|
selfRegistration
|
||||||
|
domainWhitelist
|
||||||
|
autoEnrollGroups
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -6,7 +6,7 @@ import _ from 'lodash'
|
|||||||
|
|
||||||
/* global siteConfig, graphQL */
|
/* global siteConfig, graphQL */
|
||||||
|
|
||||||
import localeQuery from 'gql/common-locale-query.gql'
|
import localeQuery from 'gql/common/common-locale-query.gql'
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
VueI18Next,
|
VueI18Next,
|
||||||
|
|||||||
+5
-3
@@ -39,12 +39,14 @@ module.exports = {
|
|||||||
_.pull(currentStrategies, 'session')
|
_.pull(currentStrategies, 'session')
|
||||||
_.forEach(currentStrategies, stg => { passport.unuse(stg) })
|
_.forEach(currentStrategies, stg => { passport.unuse(stg) })
|
||||||
|
|
||||||
// Load enable strategies
|
// Load enabled strategies
|
||||||
const enabledStrategies = await WIKI.db.authentication.getEnabledStrategies()
|
const enabledStrategies = await WIKI.db.authentication.getStrategies()
|
||||||
console.info(enabledStrategies)
|
|
||||||
for (let idx in enabledStrategies) {
|
for (let idx in enabledStrategies) {
|
||||||
const stg = enabledStrategies[idx]
|
const stg = enabledStrategies[idx]
|
||||||
|
if (!stg.isEnabled) { continue }
|
||||||
|
|
||||||
const strategy = require(`../modules/authentication/${stg.key}`)
|
const strategy = require(`../modules/authentication/${stg.key}`)
|
||||||
|
|
||||||
stg.config.callbackURL = `${WIKI.config.host}/login/${stg.key}/callback` // TODO: config.host
|
stg.config.callbackURL = `${WIKI.config.host}/login/${stg.key}/callback` // TODO: config.host
|
||||||
strategy.init(passport, stg.config)
|
strategy.init(passport, stg.config)
|
||||||
|
|
||||||
|
|||||||
@@ -31,6 +31,9 @@ exports.up = knex => {
|
|||||||
table.boolean('isEnabled').notNullable().defaultTo(false)
|
table.boolean('isEnabled').notNullable().defaultTo(false)
|
||||||
table.boolean('useForm').notNullable().defaultTo(false)
|
table.boolean('useForm').notNullable().defaultTo(false)
|
||||||
table.jsonb('config').notNullable()
|
table.jsonb('config').notNullable()
|
||||||
|
table.boolean('selfRegistration').notNullable().defaultTo(false)
|
||||||
|
table.jsonb('domainWhitelist').notNullable()
|
||||||
|
table.jsonb('autoEnrollGroups').notNullable()
|
||||||
})
|
})
|
||||||
// COMMENTS ----------------------------
|
// COMMENTS ----------------------------
|
||||||
.createTable('comments', table => {
|
.createTable('comments', table => {
|
||||||
|
|||||||
@@ -22,13 +22,21 @@ module.exports = class Authentication extends Model {
|
|||||||
title: {type: 'string'},
|
title: {type: 'string'},
|
||||||
isEnabled: {type: 'boolean'},
|
isEnabled: {type: 'boolean'},
|
||||||
useForm: {type: 'boolean'},
|
useForm: {type: 'boolean'},
|
||||||
config: {type: 'object'}
|
config: {type: 'object'},
|
||||||
|
selfRegistration: {type: 'boolean'},
|
||||||
|
domainWhitelist: {type: 'object'},
|
||||||
|
autoEnrollGroups: {type: 'object'}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static async getEnabledStrategies() {
|
static async getStrategies() {
|
||||||
return WIKI.db.authentication.query().where({ isEnabled: true })
|
const strategies = await WIKI.db.authentication.query()
|
||||||
|
return strategies.map(str => ({
|
||||||
|
...str,
|
||||||
|
domainWhitelist: _.get(str.domainWhitelist, 'v', []),
|
||||||
|
autoEnrollGroups: _.get(str.autoEnrollGroups, 'v', [])
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
static async refreshStrategiesFromDisk() {
|
static async refreshStrategiesFromDisk() {
|
||||||
@@ -46,7 +54,10 @@ module.exports = class Authentication extends Model {
|
|||||||
config: _.reduce(strategy.props, (result, value, key) => {
|
config: _.reduce(strategy.props, (result, value, key) => {
|
||||||
_.set(result, value, '')
|
_.set(result, value, '')
|
||||||
return result
|
return result
|
||||||
}, {})
|
}, {}),
|
||||||
|
selfRegistration: false,
|
||||||
|
domainWhitelist: { v: [] },
|
||||||
|
autoEnrollGroups: { v: [] }
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
AuthenticationQuery: {
|
AuthenticationQuery: {
|
||||||
async strategies(obj, args, context, info) {
|
async strategies(obj, args, context, info) {
|
||||||
let strategies = await WIKI.db.authentication.getEnabledStrategies()
|
let strategies = await WIKI.db.authentication.getStrategies()
|
||||||
strategies = strategies.map(stg => ({
|
strategies = strategies.map(stg => ({
|
||||||
...stg,
|
...stg,
|
||||||
config: _.transform(stg.config, (res, value, key) => {
|
config: _.transform(stg.config, (res, value, key) => {
|
||||||
|
|||||||
@@ -56,6 +56,9 @@ type AuthenticationStrategy {
|
|||||||
useForm: Boolean!
|
useForm: Boolean!
|
||||||
icon: String
|
icon: String
|
||||||
config: [KeyValuePair]
|
config: [KeyValuePair]
|
||||||
|
selfRegistration: Boolean!
|
||||||
|
domainWhitelist: [String]!
|
||||||
|
autoEnrollGroups: [String]!
|
||||||
}
|
}
|
||||||
|
|
||||||
type AuthenticationLoginResponse {
|
type AuthenticationLoginResponse {
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ module.exports = {
|
|||||||
return arr.filter(prvFilter.test)
|
return arr.filter(prvFilter.test)
|
||||||
},
|
},
|
||||||
orderBy (arr, orderString) {
|
orderBy (arr, orderString) {
|
||||||
let orderParams = _.zip(orderString.split(',').map(ord => _.trim(ord).split(' ').map(_.trim)))
|
let orderParams = _.zip(...orderString.split(',').map(ord => _.trim(ord).split(' ').map(_.trim)))
|
||||||
return _.orderBy(arr, orderParams[0], orderParams[1])
|
return _.orderBy(arr, orderParams[0], orderParams[1])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -8,7 +8,7 @@ const GoogleStrategy = require('passport-google-oauth20').Strategy
|
|||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
key: 'google',
|
key: 'google',
|
||||||
title: 'Google ID',
|
title: 'Google',
|
||||||
useForm: false,
|
useForm: false,
|
||||||
props: ['clientId', 'clientSecret'],
|
props: ['clientId', 'clientSecret'],
|
||||||
init (passport, conf) {
|
init (passport, conf) {
|
||||||
|
|||||||
Reference in new issue
Block a user