Skip to content

Commit 0afa65f

Browse files
committed
feat: auth self-registration config + gql grouping
1 parent 4983446 commit 0afa65f

39 files changed

+104
-50
lines changed

client/components/admin/admin-auth.vue

+29-8
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@
99

1010
v-tab-item(key='settings', :transition='false', :reverse-transition='false')
1111
v-card.pa-3(flat, tile)
12-
v-subheader.pl-0.pb-2 Select which authentication strategies to enable:
12+
.body-2.grey--text.text--darken-1 Select which authentication strategies to enable:
13+
.caption.grey--text.pb-2 Some strategies require additional configuration in their dedicated tab (when selected).
1314
v-form
1415
v-checkbox(
1516
v-for='strategy in strategies',
@@ -27,19 +28,36 @@
2728
v-form
2829
v-subheader.pl-0 Strategy Configuration
2930
.body-1.ml-3(v-if='!strategy.config || strategy.config.length < 1') This strategy has no configuration options you can modify.
30-
v-text-field(v-else, v-for='cfg in strategy.config', :key='cfg.key', :label='cfg.key', prepend-icon='settings_applications')
31+
v-text-field(
32+
v-else
33+
v-for='cfg in strategy.config'
34+
:key='cfg.key'
35+
:label='cfg.key'
36+
v-model='cfg.value'
37+
prepend-icon='settings_applications'
38+
)
3139
v-divider
3240
v-subheader.pl-0 Registration
3341
v-switch.ml-3(
34-
v-model='auths',
42+
v-model='allowSelfRegistration',
3543
label='Allow self-registration',
3644
:value='true',
3745
color='primary',
3846
hint='Allow any user successfully authorized by the strategy to access the wiki.',
3947
persistent-hint
4048
)
41-
v-text-field.ml-3(label='Limit to specific email domains', prepend-icon='mail_outline')
42-
v-text-field.ml-3(label='Assign to group', prepend-icon='people')
49+
v-text-field.ml-3(
50+
label='Limit to specific email domains'
51+
prepend-icon='mail_outline'
52+
hint='Domain(s) seperated by comma. (e.g. domain1.com, domain2.com)'
53+
persistent-hint
54+
)
55+
v-text-field.ml-3(
56+
label='Assign to group'
57+
prepend-icon='people'
58+
hint='Automatically assign new users to these groups.'
59+
persistent-hint
60+
)
4361

4462
v-card-chin
4563
v-btn(color='primary')
@@ -54,14 +72,17 @@
5472
<script>
5573
import _ from 'lodash'
5674
57-
import strategiesQuery from 'gql/admin-auth-query-strategies.gql'
58-
import strategiesSaveMutation from 'gql/admin-auth-mutation-save-strategies.gql'
75+
import strategiesQuery from 'gql/admin/auth/auth-query-strategies.gql'
76+
import strategiesSaveMutation from 'gql/admin/auth/auth-mutation-save-strategies.gql'
5977
6078
export default {
6179
data() {
6280
return {
6381
strategies: [],
64-
selectedStrategies: ['local']
82+
selectedStrategies: ['local'],
83+
selfRegistration: false,
84+
domainWhitelist: [],
85+
autoEnrollGroups: []
6586
}
6687
},
6788
computed: {

client/components/admin/admin-groups-edit.vue

+5-5
Original file line numberDiff line numberDiff line change
@@ -114,11 +114,11 @@
114114
import Criterias from '../common/criterias.vue'
115115
import UserSearch from '../common/user-search.vue'
116116
117-
import groupQuery from 'gql/admin-groups-query-single.gql'
118-
import assignUserMutation from 'gql/admin-groups-mutation-assign.gql'
119-
import deleteGroupMutation from 'gql/admin-groups-mutation-delete.gql'
120-
import unassignUserMutation from 'gql/admin-groups-mutation-unassign.gql'
121-
import updateGroupMutation from 'gql/admin-groups-mutation-update.gql'
117+
import groupQuery from 'gql/admin/groups/groups-query-single.gql'
118+
import assignUserMutation from 'gql/admin/groups/groups-mutation-assign.gql'
119+
import deleteGroupMutation from 'gql/admin/groups/groups-mutation-delete.gql'
120+
import unassignUserMutation from 'gql/admin/groups/groups-mutation-unassign.gql'
121+
import updateGroupMutation from 'gql/admin/groups/groups-mutation-update.gql'
122122
123123
export default {
124124
components: {

client/components/admin/admin-groups.vue

+4-4
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
.dialog-header.is-short New Group
1414
v-card-text
1515
v-text-field(v-model='newGroupName', label='Group Name', autofocus, counter='255', @keyup.enter='createGroup')
16-
v-card-actions
16+
v-card-chin
1717
v-spacer
1818
v-btn(flat, @click='newGroupDialog = false') Cancel
1919
v-btn(color='primary', @click='createGroup') Create
@@ -45,9 +45,9 @@
4545
<script>
4646
import _ from 'lodash'
4747
48-
import groupsQuery from 'gql/admin-groups-query-list.gql'
49-
import createGroupMutation from 'gql/admin-groups-mutation-create.gql'
50-
import deleteGroupMutation from 'gql/admin-groups-mutation-delete.gql'
48+
import groupsQuery from 'gql/admin/groups/groups-query-list.gql'
49+
import createGroupMutation from 'gql/admin/groups/groups-mutation-create.gql'
50+
import deleteGroupMutation from 'gql/admin/groups/groups-mutation-delete.gql'
5151
5252
export default {
5353
data() {

client/components/admin/admin-locale.vue

+3-3
Original file line numberDiff line numberDiff line change
@@ -128,9 +128,9 @@ import _ from 'lodash'
128128
129129
/* global WIKI */
130130
131-
import localesQuery from 'gql/admin-locale-query-list.gql'
132-
import localesDownloadMutation from 'gql/admin-locale-mutation-download.gql'
133-
import localesSaveMutation from 'gql/admin-locale-mutation-save.gql'
131+
import localesQuery from 'gql/admin/locale/locale-query-list.gql'
132+
import localesDownloadMutation from 'gql/admin/locale/locale-mutation-download.gql'
133+
import localesSaveMutation from 'gql/admin/locale/locale-mutation-save.gql'
134134
135135
export default {
136136
data() {

client/components/admin/admin-system.vue

+1-1
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ import IconCube from 'mdi/cube'
106106
import IconDatabase from 'mdi/database'
107107
import IconNodeJs from 'mdi/nodejs'
108108
109-
import systemInfoQuery from 'gql/admin-system-query-info.gql'
109+
import systemInfoQuery from 'gql/admin/system/system-query-info.gql'
110110
111111
export default {
112112
components: {

client/components/admin/admin-theme.vue

+1-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@
5050
<script>
5151
import _ from 'lodash'
5252
53-
import themeSaveMutation from 'gql/admin-theme-mutation-save.gql'
53+
import themeSaveMutation from 'gql/admin/theme/theme-mutation-save.gql'
5454
5555
export default {
5656
data() {

client/components/common/user-search.vue

+1-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@
4848
<script>
4949
import _ from 'lodash'
5050
51-
import searchUsersQuery from 'gql/common-users-query-search.gql'
51+
import searchUsersQuery from 'gql/common/common-users-query-search.gql'
5252
5353
export default {
5454
filters: {

client/components/login.vue

+3-3
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,9 @@
5656
import _ from 'lodash'
5757
import { mapState } from 'vuex'
5858
59-
import strategiesQuery from 'gql/login-query-strategies.gql'
60-
import loginMutation from 'gql/login-mutation-login.gql'
61-
import tfaMutation from 'gql/login-mutation-tfa.gql'
59+
import strategiesQuery from 'gql/login/login-query-strategies.gql'
60+
import loginMutation from 'gql/login/login-mutation-login.gql'
61+
import tfaMutation from 'gql/login/login-mutation-tfa.gql'
6262
6363
export default {
6464
i18nOptions: { namespaces: 'auth' },

client/components/profile.vue

+5-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<template lang='pug'>
2-
v-app.profile
2+
v-app(:dark='darkMode').profile
33
nav-header
44
v-navigation-drawer.pb-0(v-model='profileDrawerShown', app, fixed, clipped, left, permanent)
55
v-list(dense)
@@ -22,7 +22,7 @@
2222
transition(name='profile-router')
2323
router-view
2424

25-
v-footer.py-2.justify-center(app, absolute, color='grey lighten-3', inset, height='auto')
25+
v-footer.py-2.justify-center(app, absolute, :color='darkMode ? "" : "grey lighten-3"', inset, height='auto')
2626
.caption.grey--text.text--darken-1 Powered by Wiki.js
2727

2828
v-snackbar(
@@ -41,7 +41,7 @@
4141
import VueRouter from 'vue-router'
4242
import { mapState } from 'vuex'
4343
44-
/* global WIKI */
44+
/* global WIKI, siteConfig */
4545
4646
const router = new VueRouter({
4747
mode: 'history',
@@ -75,7 +75,8 @@ export default {
7575
notificationState: {
7676
get() { return this.notification.isActive },
7777
set(newState) { this.$store.commit('updateNotificationState', newState) }
78-
}
78+
},
79+
darkMode() { return siteConfig.darkMode }
7980
},
8081
router
8182
}

client/components/profile/preferences.vue

+6-4
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,7 @@
1818
v-divider
1919
v-subheader.pl-0 Timezone
2020
v-select.grey.lighten-5(solo, flat)
21-
v-divider.my-0
22-
v-card-actions.grey.lighten-4
21+
v-card-chin
2322
v-spacer
2423
v-btn(color='primary')
2524
v-icon(left) chevron_right
@@ -32,8 +31,7 @@
3231
v-card-text
3332
v-subheader.pl-0 Default Editor
3433
v-select.grey.lighten-5(solo, flat)
35-
v-divider.my-0
36-
v-card-actions.grey.lighten-4
34+
v-card-chin
3735
v-spacer
3836
v-btn(color='primary')
3937
v-icon(left) chevron_right
@@ -42,10 +40,14 @@
4240
</template>
4341

4442
<script>
43+
/* global siteConfig */
4544
4645
export default {
4746
data() {
4847
return { }
48+
},
49+
computed: {
50+
darkMode() { return siteConfig.darkMode }
4951
}
5052
}
5153
</script>

client/components/profile/profile.vue

+12-4
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,7 @@
1717
v-text-field(label='Name', :counter='255', v-model='name', prepend-icon='person')
1818
v-text-field(label='Job Title', :counter='255', prepend-icon='accessibility')
1919
v-text-field(label='Location / Office', :counter='255', prepend-icon='location_on')
20-
v-divider.my-0
21-
v-card-actions.grey.lighten-4
20+
v-card-chin
2221
v-spacer
2322
v-btn(color='primary')
2423
v-icon(left) chevron_right
@@ -29,8 +28,13 @@
2928
.subheading Authentication
3029
v-card-text
3130
v-subheader.pl-0 Provider
32-
v-toolbar(flat, color='purple lighten-5', dense).purple--text.text--darken-4
33-
v-icon(color='purple darken-4') supervised_user_circle
31+
v-toolbar(
32+
flat
33+
:color='darkMode ? "grey darken-2" : "purple lighten-5"'
34+
dense
35+
:class='darkMode ? "grey--text text--lighten-1" : "purple--text text--darken-4"'
36+
)
37+
v-icon(:color='darkMode ? "grey lighten-1" : "purple darken-4"') supervised_user_circle
3438
.subheading.ml-3 Local
3539
v-divider
3640
v-subheader.pl-0 Two-Factor Authentication (2FA)
@@ -72,12 +76,16 @@
7276
</template>
7377

7478
<script>
79+
/* global siteConfig */
7580
7681
export default {
7782
data() {
7883
return {
7984
name: 'John Doe'
8085
}
86+
},
87+
computed: {
88+
darkMode() { return siteConfig.darkMode }
8189
}
8290
}
8391
</script>

client/graph/admin-auth-query-strategies.gql renamed to client/graph/admin/auth/auth-query-strategies.gql

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
query {
22
authentication {
3-
strategies {
3+
strategies(orderBy: "title ASC") {
44
isEnabled
55
key
66
props
@@ -10,6 +10,9 @@ query {
1010
key
1111
value
1212
}
13+
selfRegistration
14+
domainWhitelist
15+
autoEnrollGroups
1316
}
1417
}
1518
}

client/modules/localization.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import _ from 'lodash'
66

77
/* global siteConfig, graphQL */
88

9-
import localeQuery from 'gql/common-locale-query.gql'
9+
import localeQuery from 'gql/common/common-locale-query.gql'
1010

1111
module.exports = {
1212
VueI18Next,

server/core/auth.js

+5-3
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,14 @@ module.exports = {
3939
_.pull(currentStrategies, 'session')
4040
_.forEach(currentStrategies, stg => { passport.unuse(stg) })
4141

42-
// Load enable strategies
43-
const enabledStrategies = await WIKI.db.authentication.getEnabledStrategies()
44-
console.info(enabledStrategies)
42+
// Load enabled strategies
43+
const enabledStrategies = await WIKI.db.authentication.getStrategies()
4544
for (let idx in enabledStrategies) {
4645
const stg = enabledStrategies[idx]
46+
if (!stg.isEnabled) { continue }
47+
4748
const strategy = require(`../modules/authentication/${stg.key}`)
49+
4850
stg.config.callbackURL = `${WIKI.config.host}/login/${stg.key}/callback` // TODO: config.host
4951
strategy.init(passport, stg.config)
5052

server/db/migrations/2.0.0.js

+3
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ exports.up = knex => {
3131
table.boolean('isEnabled').notNullable().defaultTo(false)
3232
table.boolean('useForm').notNullable().defaultTo(false)
3333
table.jsonb('config').notNullable()
34+
table.boolean('selfRegistration').notNullable().defaultTo(false)
35+
table.jsonb('domainWhitelist').notNullable()
36+
table.jsonb('autoEnrollGroups').notNullable()
3437
})
3538
// COMMENTS ----------------------------
3639
.createTable('comments', table => {

server/db/models/authentication.js

+15-4
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,21 @@ module.exports = class Authentication extends Model {
2222
title: {type: 'string'},
2323
isEnabled: {type: 'boolean'},
2424
useForm: {type: 'boolean'},
25-
config: {type: 'object'}
25+
config: {type: 'object'},
26+
selfRegistration: {type: 'boolean'},
27+
domainWhitelist: {type: 'object'},
28+
autoEnrollGroups: {type: 'object'}
2629
}
2730
}
2831
}
2932

30-
static async getEnabledStrategies() {
31-
return WIKI.db.authentication.query().where({ isEnabled: true })
33+
static async getStrategies() {
34+
const strategies = await WIKI.db.authentication.query()
35+
return strategies.map(str => ({
36+
...str,
37+
domainWhitelist: _.get(str.domainWhitelist, 'v', []),
38+
autoEnrollGroups: _.get(str.autoEnrollGroups, 'v', [])
39+
}))
3240
}
3341

3442
static async refreshStrategiesFromDisk() {
@@ -46,7 +54,10 @@ module.exports = class Authentication extends Model {
4654
config: _.reduce(strategy.props, (result, value, key) => {
4755
_.set(result, value, '')
4856
return result
49-
}, {})
57+
}, {}),
58+
selfRegistration: false,
59+
domainWhitelist: { v: [] },
60+
autoEnrollGroups: { v: [] }
5061
})
5162
}
5263
})

server/graph/resolvers/authentication.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ module.exports = {
1616
},
1717
AuthenticationQuery: {
1818
async strategies(obj, args, context, info) {
19-
let strategies = await WIKI.db.authentication.getEnabledStrategies()
19+
let strategies = await WIKI.db.authentication.getStrategies()
2020
strategies = strategies.map(stg => ({
2121
...stg,
2222
config: _.transform(stg.config, (res, value, key) => {

server/graph/schemas/authentication.graphql

+3
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,9 @@ type AuthenticationStrategy {
5656
useForm: Boolean!
5757
icon: String
5858
config: [KeyValuePair]
59+
selfRegistration: Boolean!
60+
domainWhitelist: [String]!
61+
autoEnrollGroups: [String]!
5962
}
6063

6164
type AuthenticationLoginResponse {

server/helpers/graph.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ module.exports = {
2424
return arr.filter(prvFilter.test)
2525
},
2626
orderBy (arr, orderString) {
27-
let orderParams = _.zip(orderString.split(',').map(ord => _.trim(ord).split(' ').map(_.trim)))
27+
let orderParams = _.zip(...orderString.split(',').map(ord => _.trim(ord).split(' ').map(_.trim)))
2828
return _.orderBy(arr, orderParams[0], orderParams[1])
2929
}
3030
}

0 commit comments

Comments
 (0)