Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wiki-js
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
1
Issues
1
List
Board
Labels
Milestones
Merge Requests
1
Merge Requests
1
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
wiki-js
Commits
2d2cf905
Commit
2d2cf905
authored
Aug 10, 2019
by
Nick
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: admin create user + markdown help fix
parent
577a0610
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
234 additions
and
203 deletions
+234
-203
client-app.js
client/client-app.js
+1
-1
admin.vue
client/components/admin.vue
+6
-6
admin-groups-edit-permissions.vue
client/components/admin/admin-groups-edit-permissions.vue
+8
-9
admin-groups-edit-rules.vue
client/components/admin/admin-groups-edit-rules.vue
+0
-0
admin-groups-edit-users.vue
client/components/admin/admin-groups-edit-users.vue
+22
-18
admin-groups-edit.vue
client/components/admin/admin-groups-edit.vue
+9
-8
admin-groups.vue
client/components/admin/admin-groups.vue
+17
-19
admin-storage.vue
client/components/admin/admin-storage.vue
+4
-4
admin-users-create.vue
client/components/admin/admin-users-create.vue
+13
-7
admin-users-edit.vue
client/components/admin/admin-users-edit.vue
+0
-0
admin-users.vue
client/components/admin/admin-users.vue
+23
-51
user-search.vue
client/components/common/user-search.vue
+5
-5
help.vue
client/components/editor/markdown/help.vue
+38
-41
login.vue
client/components/login.vue
+1
-1
v-data-table.scss
client/scss/components/v-data-table.scss
+1
-1
user.js
server/graph/resolvers/user.js
+11
-2
users.js
server/models/users.js
+75
-30
No files found.
client/client-app.js
View file @
2d2cf905
...
...
@@ -64,7 +64,7 @@ const graphQLLink = ApolloLink.from([
)
store
.
commit
(
'showNotification'
,
{
style
:
'red'
,
message
:
`An expected error occured.`
,
message
:
`An
un
expected error occured.`
,
icon
:
'warning'
})
}
...
...
client/components/admin.vue
View file @
2d2cf905
...
...
@@ -26,8 +26,8 @@
v-list-item(to='/pages', v-if='hasPermission([`manage:system`, `write:pages`, `manage:pages`, `delete:pages`])')
v-list-item-avatar(size='24'): v-icon mdi-file-document-outline
v-list-item-title
{{
$t
(
'admin:pages.title'
)
}}
v-list-item-action
v-chip(x-small,
disabled, :color='darkMode ? `grey darken-3-d4` : `grey lighten-4
`')
v-list-item-action
.pr-3
v-chip(x-small,
:color='darkMode ? `grey darken-3-d4` : `grey lighten-5
`')
.caption.grey--text
{{
info
.
pagesTotal
}}
v-list-item(to='/theme', v-if='hasPermission([`manage:system`, `manage:theme`])')
v-list-item-avatar(size='24'): v-icon mdi-palette-outline
...
...
@@ -38,14 +38,14 @@
v-list-item(to='/groups', v-if='hasPermission([`manage:system`, `manage:groups`, `write:groups`])')
v-list-item-avatar(size='24'): v-icon mdi-account-group
v-list-item-title
{{
$t
(
'admin:groups.title'
)
}}
v-list-item-action
v-chip(x-small,
disabled,
:color='darkMode ? `grey darken-3-d4` : `grey lighten-4`')
v-list-item-action
.pr-3
v-chip(x-small, :color='darkMode ? `grey darken-3-d4` : `grey lighten-4`')
.caption.grey--text
{{
info
.
groupsTotal
}}
v-list-item(to='/users', v-if='hasPermission([`manage:system`, `manage:groups`, `write:groups`, `manage:users`, `write:users`])')
v-list-item-avatar(size='24'): v-icon mdi-account-box
v-list-item-title
{{
$t
(
'admin:users.title'
)
}}
v-list-item-action
v-chip(x-small,
disabled,
:color='darkMode ? `grey darken-3-d4` : `grey lighten-4`')
v-list-item-action
.pr-3
v-chip(x-small, :color='darkMode ? `grey darken-3-d4` : `grey lighten-4`')
.caption.grey--text
{{
info
.
usersTotal
}}
template(v-if='hasPermission(`manage:system`)')
v-divider.my-2
...
...
client/components/admin/admin-groups-edit-permissions.vue
View file @
2d2cf905
<
template
lang=
"pug"
>
v-card
.wiki-form
(flat)
v-card(flat)
v-card-text
v-text-field(
outline
background-color='grey lighten-3'
outlined
v-model='group.name'
label='Group Name'
counter='255'
prepend-icon='
people
'
prepend-icon='
mdi-account-group
'
)
v-alert.radius-7(
v-if='group.isSystem'
color='orange darken-2'
:class='$vuetify.theme.dark ? "grey darken-4" : "orange lighten-5"'
outline
outline
d
:value='true'
icon='
lock_
outline'
icon='
mdi-lock-
outline'
) This is a system group. Some permissions cannot be modified.
v-container.px-3.pb-3.pt-0(fluid, grid-list-md)
v-layout(row, wrap)
v-flex(xs12, md6, lg4, v-for='pmGroup in permissions', :key='pmGroup.category')
v-card.md2(flat, :class='$vuetify.theme.dark ? "grey darken-3-d5" : "
white
"')
v-subheader
{{
pmGroup
.
category
}}
v-card.md2(flat, :class='$vuetify.theme.dark ? "grey darken-3-d5" : "
grey lighten-5
"')
.overline.px-5.pt-5.pb-3.grey--text.text--darken-2
{{
pmGroup
.
category
}}
v-card-text.pt-0
template(v-for='(pm, idx) in pmGroup.items')
v-checkbox.pt-0(
...
...
@@ -32,7 +31,7 @@
color='primary'
v-model='group.permissions'
:value='pm.permission'
:append-icon='pm.warning ? "
warning
" : null',
:append-icon='pm.warning ? "
mdi-alert
" : null',
:disabled='(group.isSystem && pm.restrictedForSystem) || group.id === 1 || pm.disabled'
)
v-divider.mt-3(v-if='idx < pmGroup.items.length - 1')
...
...
client/components/admin/admin-groups-edit-rules.vue
View file @
2d2cf905
This diff is collapsed.
Click to expand it.
client/components/admin/admin-groups-edit-users.vue
View file @
2d2cf905
<
template
lang=
"pug"
>
v-card
.wiki-form
v-card-title(:class='$vuetify.theme.dark ? `grey darken-3-d3` : `grey lighten-5`')
v-card
v-card-title
.pb-4
(:class='$vuetify.theme.dark ? `grey darken-3-d3` : `grey lighten-5`')
v-text-field(
outline
outline
d
flat
prepend-inner-icon='
search
'
prepend-inner-icon='
mdi-magnify
'
v-model='search'
label='Search Group Users...'
hide-details
)
v-spacer
v-btn(color='primary', depressed, @click='searchUserDialog = true', :disabled='group.id === 2')
v-icon(left)
assignment_ind
v-icon(left)
mdi-clipboard-account
| Assign User
v-data-table(
:items='group.users',
:headers='headers',
:search='search'
:pagination.sync='pagination',
:rows-per-page-items='[15]'
hide-actions
:page.sync='pagination'
:items-per-page='15'
@page-count='pageCount = $event'
must-sort,
hide-default-footer
)
template(slot='item
s
', slot-scope='props')
template(slot='item', slot-scope='props')
tr(:active='props.selected')
td.text-xs-right
{{
props
.
item
.
id
}}
td
{{
props
.
item
.
name
}}
td
{{
props
.
item
.
email
}}
td
v-menu(bottom, right, min-width='200')
v-btn(icon, slot='activator'): v-icon.grey--text.text--darken-1 more_horiz
v-list
template(v-slot:activator='{ on }')
v-btn(icon, v-on='on', small)
v-icon.grey--text.text--darken-1 mdi-dots-horizontal
v-list(dense, nav)
v-list-item(:to='`/users/` + props.item.id')
v-list-item-action: v-icon(color='primary')
person
v-list-item-action: v-icon(color='primary')
mdi-account-outline
v-list-item-content
v-list-item-title View User Profile
template(v-if='props.item.id !== 2')
v-divider
v-list-item(@click='unassignUser(props.item.id)')
v-list-item-action: v-icon(color='orange')
highlight_off
v-list-item-action: v-icon(color='orange')
mdi-account-remove-outline
v-list-item-content
v-list-item-title Unassign
template(slot='no-data')
v-alert.ma-3(icon='warning',
:value='true', outline
) No users to display.
.text-
xs-
center.py-2(v-if='group.users.length > 15')
v-pagination(v-model='pagination
.page', :length='pages
')
v-alert.ma-3(icon='warning',
outlined
) No users to display.
.text-center.py-2(v-if='group.users.length > 15')
v-pagination(v-model='pagination
', :length='pageCount
')
user-search(v-model='searchUserDialog', @select='assignUser')
</
template
>
...
...
@@ -73,7 +76,8 @@ export default {
{
text
:
''
,
value
:
'actions'
,
sortable
:
false
,
width
:
50
}
],
searchUserDialog
:
false
,
pagination
:
{},
pagination
:
1
,
pageCount
:
0
,
search
:
''
}
},
...
...
client/components/admin/admin-groups-edit.vue
View file @
2d2cf905
...
...
@@ -10,11 +10,12 @@
v-spacer
.caption.grey--text ID #[strong
{{
group
.
id
}}
]
v-divider.mx-3(vertical)
v-btn(color='grey', large, outline, to='/groups')
v-icon
arrow_back
v-btn(color='grey', large, outline
d
, to='/groups')
v-icon
mdi-arrow-left
v-dialog(v-model='deleteGroupDialog', max-width='500', v-if='!group.isSystem')
v-btn(color='red', large, outline, slot='activator')
v-icon(color='red') delete
template(v-slot:activator='{ on }')
v-btn(color='red', large, outlined, v-on='{ on }')
v-icon(color='red') mdi-trash-can-outline
v-card
.dialog-header.is-red Delete Group?
v-card-text Are you sure you want to delete group #[strong
{{
group
.
name
}}
]? All users will be unassigned from this group.
...
...
@@ -22,11 +23,11 @@
v-spacer
v-btn(flat, @click='deleteGroupDialog = false') Cancel
v-btn(color='red', dark, @click='deleteGroup') Delete
v-btn(color='success', large, depressed, @click='updateGroup')
v-icon(left) check
v-btn
.ml-2
(color='success', large, depressed, @click='updateGroup')
v-icon(left)
mdi-
check
span Update Group
v-card.mt-3
v-tabs(v-model='tab', :color='$vuetify.theme.dark ? "primary" : "grey darken-2"', fixed-tabs, slider-color='white', show-arrows, dark)
v-tabs(v-model='tab', :
background-
color='$vuetify.theme.dark ? "primary" : "grey darken-2"', fixed-tabs, slider-color='white', show-arrows, dark)
v-tab(key='permissions') Permissions
v-tab(key='rules') Page Rules
v-tab(key='users') Users
...
...
@@ -69,7 +70,7 @@ export default {
users
:
[]
},
deleteGroupDialog
:
false
,
tab
:
'1'
tab
:
null
}
},
methods
:
{
...
...
client/components/admin/admin-groups.vue
View file @
2d2cf905
...
...
@@ -37,25 +37,29 @@
:items='groups'
:headers='headers'
:search='search'
:pagination.sync='pagination'
:rows-per-page-items='[15]'
hide-actions
:page.sync='pagination'
:items-per-page='15'
:loading='loading'
@page-count='pageCount = $event'
must-sort,
hide-default-footer
)
template(slot='item
s
', slot-scope='props')
template(slot='item', slot-scope='props')
tr.is-clickable(:active='props.selected', @click='$router.push("/groups/" + props.item.id)')
td
.text-xs-right
{{
props
.
item
.
id
}}
td
{{
props
.
item
.
id
}}
td: strong
{{
props
.
item
.
name
}}
td
{{
props
.
item
.
userCount
}}
td
{{
props
.
item
.
createdAt
|
moment
(
'calendar'
)
}}
td
{{
props
.
item
.
updatedAt
|
moment
(
'calendar'
)
}}
td
v-tooltip(left, v-if='props.item.isSystem')
v-icon(slot='activator') lock_outline
template(v-slot:activator='{ on }')
v-icon(v-on='on') mdi-lock-outline
span System Group
template(slot='no-data')
v-alert.ma-3(icon='warning', :value='true', outline) No groups to display.
.text-xs-center.py-2(v-if='
this.pages > 0
')
v-pagination(v-model='pagination
.page', :length='pages
')
.text-xs-center.py-2(v-if='
pageCount > 1
')
v-pagination(v-model='pagination
', :length='pageCount
')
</
template
>
<
script
>
...
...
@@ -70,7 +74,8 @@ export default {
newGroupDialog
:
false
,
newGroupName
:
''
,
selectedGroup
:
{},
pagination
:
{},
pagination
:
1
,
pageCount
:
0
,
groups
:
[],
headers
:
[
{
text
:
'ID'
,
value
:
'id'
,
width
:
50
,
align
:
'right'
},
...
...
@@ -80,16 +85,8 @@ export default {
{
text
:
'Last Updated'
,
value
:
'updatedAt'
,
width
:
250
},
{
text
:
''
,
value
:
'isSystem'
,
width
:
20
,
sortable
:
false
}
],
search
:
''
}
},
computed
:
{
pages
()
{
if
(
this
.
pagination
.
rowsPerPage
==
null
||
this
.
pagination
.
totalItems
==
null
)
{
return
0
}
return
Math
.
ceil
(
this
.
pagination
.
totalItems
/
this
.
pagination
.
rowsPerPage
)
search
:
''
,
loading
:
false
}
},
watch
:
{
...
...
@@ -158,6 +155,7 @@ export default {
fetchPolicy
:
'network-only'
,
update
:
(
data
)
=>
data
.
groups
.
list
,
watchLoading
(
isLoading
)
{
this
.
loading
=
isLoading
this
.
$store
.
commit
(
`loading
${
isLoading
?
'Start'
:
'Stop'
}
`
,
'admin-groups-refresh'
)
}
}
...
...
client/components/admin/admin-storage.vue
View file @
2d2cf905
...
...
@@ -46,7 +46,7 @@
v-list-item(:key='tgt.key')
template(v-if='tgt.status === `pending`')
v-list-item-avatar(color='purple')
v-icon(color='white')
schedul
e
v-icon(color='white')
mdi-clock-outlin
e
v-list-item-content
v-list-item-title.body-2
{{
tgt
.
title
}}
v-list-item-sub-title.purple--text.caption
{{
tgt
.
status
}}
...
...
@@ -54,20 +54,20 @@
v-progress-circular(indeterminate, :size='20', :width='2', color='purple')
template(v-else-if='tgt.status === `operational`')
v-list-item-avatar(color='green')
v-icon(color='white')
check_
circle
v-icon(color='white')
mdi-check-
circle
v-list-item-content
v-list-item-title.body-2
{{
tgt
.
title
}}
v-list-item-sub-title.green--text.caption
{{
$t
(
'admin:storage.lastSync'
,
{
time
:
$options
.
filters
.
moment
(
tgt
.
lastAttempt
,
'from'
)
}
)
}}
template
(
v
-
else
)
v
-
list
-
item
-
avatar
(
color
=
'red'
)
v
-
icon
(
color
=
'white'
)
highlight_off
v
-
icon
(
color
=
'white'
)
mdi
-
close
-
circle
-
outline
v
-
list
-
item
-
content
v
-
list
-
item
-
title
.
body
-
2
{{
tgt
.
title
}}
v
-
list
-
item
-
sub
-
title
.
red
--
text
.
caption
{{
$t
(
'admin:storage.lastSyncAttempt'
,
{
time
:
$options
.
filters
.
moment
(
tgt
.
lastAttempt
,
'from'
)
}
)
}}
v
-
list
-
item
-
action
v
-
menu
v
-
btn
(
slot
=
'activator'
,
icon
)
v
-
icon
(
color
=
'red'
)
info
v
-
icon
(
color
=
'red'
)
mdi
-
information
v
-
card
(
width
=
'450'
)
v
-
toolbar
(
flat
,
color
=
'red'
,
dark
,
dense
)
{{
$t
(
'admin:storage.errorMsg'
)
}}
v
-
card
-
text
{{
tgt
.
message
}}
...
...
client/components/admin/admin-users-create.vue
View file @
2d2cf905
<
template
lang=
"pug"
>
v-dialog(v-model='isShown', max-width='650', persistent)
v-card
.wiki-form
v-card
.dialog-header.is-short
v-icon.mr-3(color='white') mdi-plus
span New User
...
...
@@ -59,13 +59,14 @@
data-vv-as='Name',
data-vv-scope='newUser',
:error-messages='errors.collect(`newUser.name`)'
:hint='provider === `local` ? `Can be changed by the user.` : `May be overwritten by the provider during login.`'
key='newUserName'
persistent-hint
)
v-select(
v-select
.mt-2
(
:items='groups'
item-text='name'
item-value='
key
'
item-value='
id
'
outlined
prepend-icon='mdi-account-group'
v-model='group'
...
...
@@ -90,8 +91,12 @@
v-card-chin
v-spacer
v-btn(text, @click='isShown = false') Cancel
v-btn(depressed, color='primary', @click='newUser(false)', :disabled='errors.any(`newUser`)') Create
v-btn(depressed, color='primary', @click='newUser(true)', :disabled='errors.any(`newUser`)') Create and Close
v-btn.px-3(depressed, color='primary', @click='newUser(false)', :disabled='errors.any(`newUser`)')
v-icon(left) mdi-chevron-right
span Create
v-btn.px-3(depressed, color='primary', @click='newUser(true)', :disabled='errors.any(`newUser`)')
v-icon(left) mdi-chevron-double-right
span Create and Close
</
template
>
<
script
>
...
...
@@ -116,7 +121,7 @@ export default {
password
:
''
,
name
:
''
,
groups
:
[],
group
:
''
,
group
:
[]
,
mustChangePwd
:
false
,
sendWelcomeEmail
:
false
}
...
...
@@ -155,7 +160,7 @@ export default {
email
:
this
.
email
,
passwordRaw
:
this
.
password
,
name
:
this
.
name
,
groups
:
this
.
group
s
,
groups
:
this
.
group
,
mustChangePassword
:
this
.
mustChangePwd
,
sendWelcomeEmail
:
this
.
sendWelcomeEmail
},
...
...
@@ -176,6 +181,7 @@ export default {
if
(
close
)
{
this
.
isShown
=
false
this
.
$emit
(
'refresh'
)
}
else
{
this
.
$refs
.
emailInput
.
focus
()
}
...
...
client/components/admin/admin-users-edit.vue
View file @
2d2cf905
This diff is collapsed.
Click to expand it.
client/components/admin/admin-users.vue
View file @
2d2cf905
...
...
@@ -39,45 +39,36 @@
:items='usersFiltered',
:headers='headers',
:search='search',
:pag
ination.sync='pagination',
:
rows-per-page-items='[15]
'
:pag
e.sync='pagination'
:
items-per-page='15
'
:loading='loading'
hide-actions,
disable-initial-sort
)
template(slot='headers', slot-scope='props')
tr
th.text-xs-left(
v-for='header in props.headers'
:key='header.text'
:width='header.width'
:class='[`column`, header.sortable ? `sortable` : ``, pagination.descending ? `desc` : `asc`, header.value === pagination.sortBy ? `active` : ``]'
@click='changeSort(header.value)'
)
|
{{
header
.
text
}}
v-icon(small, v-if='header.sortable') arrow_upward
template(slot='items', slot-scope='props')
@page-count='pageCount = $event'
hide-default-footer
)
template(slot='item', slot-scope='props')
tr.is-clickable(:active='props.selected', @click='$router.push("/users/" + props.item.id)')
//- td
v-checkbox(hide-details, :input-value='props.selected', color='blue darken-2', @click='props.selected = !props.selected')
td
.text-xs-right
{{
props
.
item
.
id
}}
td
{{
props
.
item
.
id
}}
td: strong
{{
props
.
item
.
name
}}
td
{{
props
.
item
.
email
}}
td
{{
props
.
item
.
providerKey
}}
td
{{
props
.
item
.
createdAt
|
moment
(
'from'
)
}}
td
v-tooltip(left, v-if='props.item.isSystem')
v-icon(slot='activator') lock_outline
template(v-slot:activator='{ on }')
v-icon(v-on='{ on }') mdi-lock-outline
span System User
template(slot='no-data')
.pa-3
v-alert(icon='warning', :value='true', outline) No users to display!
v-card-chin(v-if='this.pages > 1')
v-alert.text-left(icon='mdi-alert', outlined, color='grey')
em.body-2 No users to display!
v-card-chin(v-if='pageCount > 1')
v-spacer
v-pagination(v-model='pagination
.page', :length='pages
')
v-pagination(v-model='pagination
', :length='pageCount
')
v-spacer
user-create(v-model='isCreateDialogShown')
user-create(v-model='isCreateDialogShown'
, @refresh='refresh(false)'
)
</
template
>
<
script
>
...
...
@@ -95,7 +86,8 @@ export default {
data
()
{
return
{
selected
:
[],
pagination
:
{},
pagination
:
1
,
pageCount
:
0
,
users
:
[],
headers
:
[
{
text
:
'ID'
,
value
:
'id'
,
width
:
80
,
sortable
:
true
},
...
...
@@ -116,40 +108,20 @@ export default {
usersFiltered
()
{
const
all
=
this
.
filterStrategy
===
'all'
||
this
.
filterStrategy
===
''
return
_
.
filter
(
this
.
users
,
u
=>
all
||
u
.
providerKey
===
this
.
filterStrategy
)
},
pages
()
{
if
(
this
.
pagination
.
rowsPerPage
==
null
||
this
.
usersFiltered
.
length
<
1
)
{
return
0
}
return
Math
.
ceil
(
this
.
usersFiltered
.
length
/
this
.
pagination
.
rowsPerPage
)
}
},
methods
:
{
createUser
()
{
this
.
isCreateDialogShown
=
true
},
async
refresh
()
{
async
refresh
(
notify
=
true
)
{
await
this
.
$apollo
.
queries
.
users
.
refetch
()
this
.
$store
.
commit
(
'showNotification'
,
{
message
:
'Users list has been refreshed.'
,
style
:
'success'
,
icon
:
'cached'
})
},
changeSort
(
column
)
{
if
(
this
.
pagination
.
sortBy
===
column
)
{
this
.
pagination
.
descending
=
!
this
.
pagination
.
descending
}
else
{
this
.
pagination
.
sortBy
=
column
this
.
pagination
.
descending
=
false
}
},
toggleAll
()
{
if
(
this
.
selected
.
length
)
{
this
.
selected
=
[]
}
else
{
this
.
selected
=
this
.
items
.
slice
()
if
(
notify
)
{
this
.
$store
.
commit
(
'showNotification'
,
{
message
:
'Users list has been refreshed.'
,
style
:
'success'
,
icon
:
'cached'
})
}
}
},
...
...
client/components/common/user-search.vue
View file @
2d2cf905
...
...
@@ -16,10 +16,10 @@
)
v-card-text
v-text-field(
outline
outline
d
:label='$t(`common:user.searchPlaceholder`)'
v-model='search'
prepend-inner-icon='
search
'
prepend-inner-icon='
mdi-account-search-outline
'
color='primary'
ref='searchIpt'
hide-details
...
...
@@ -35,14 +35,14 @@
span.body-1.white--text
{{
usr
.
name
|
initials
}}
v-list-item-content
v-list-item-title.body-2
{{
usr
.
name
}}
v-list-item-sub
-
title
{{
usr
.
email
}}
v-list-item-subtitle
{{
usr
.
email
}}
v-list-item-action
v-icon(color='primary')
arrow_forward
v-icon(color='primary')
mdi-arrow-right
v-divider.my-0(v-if='idx < items.length - 1')
v-card-chin
v-spacer
v-btn(
fla
t
tex
t
@click='close'
:disabled='loading'
)
{{
$t
(
'common:actions.cancel'
)
}}
...
...
client/components/editor/markdown/help.vue
View file @
2d2cf905
...
...
@@ -7,7 +7,7 @@
v-card-text
.d-flex
v-toolbar.radius-7(color='teal lighten-5', dense, flat, height='44')
v-icon.mr-3(color='teal')
info
v-icon.mr-3(color='teal')
mdi-information-variant
.body-2.teal--text Markdown Reference
.body-2.mt-3 Bold
v-layout(row)
...
...
@@ -15,8 +15,8 @@
v-card.editor-markdown-help-source(flat)
v-card-text
div **Lorem ipsum**
v-icon
chevron_
right
v-flex
(xs6)
v-icon
mdi-chevron-
right
v-flex
v-card.editor-markdown-help-result(flat)
v-card-text
.caption: strong Lorem ipsum
...
...
@@ -26,8 +26,8 @@
v-card.editor-markdown-help-source(flat)
v-card-text
div *Lorem ipsum*
v-icon
chevron_
right
v-flex
(xs6)
v-icon
mdi-chevron-
right
v-flex
v-card.editor-markdown-help-result(flat)
v-card-text
.caption: em Lorem ipsum
...
...
@@ -37,8 +37,8 @@
v-card.editor-markdown-help-source(flat)
v-card-text
div ~~Lorem ipsum~~
v-icon
chevron_
right
v-flex
(xs6)
v-icon
mdi-chevron-
right
v-flex
v-card.editor-markdown-help-result(flat)
v-card-text
.caption(style='text-decoration: line-through;') Lorem ipsum
...
...
@@ -53,8 +53,8 @@
div #### Header 4
div ##### Header 5
div ###### Header 6
v-icon
chevron_
right
v-flex
(xs6)
v-icon
mdi-chevron-
right
v-flex
v-card.editor-markdown-help-result(flat)
v-card-text
div(style='font-weight: 700; font-size: 24px;') Header 1
...
...
@@ -72,8 +72,8 @@
div - Unordered List Item 1
div - Unordered List Item 2
div - Unordered List Item 3
v-icon
chevron_
right
v-flex
(xs6)
v-icon
mdi-chevron-
right
v-flex
v-card.editor-markdown-help-result(flat)
v-card-text
ul
...
...
@@ -89,8 +89,8 @@
div 1. Ordered List Item 1
div 1. Ordered List Item 2
div 1. Ordered List Item 3
v-icon
chevron_
right
v-flex
(xs6)
v-icon
mdi-chevron-
right
v-flex
v-card.editor-markdown-help-result(flat)
v-card-text
ol
...
...
@@ -103,8 +103,8 @@
v-card.editor-markdown-help-source(flat)
v-card-text
div ![Caption Text](/path/to/image.jpg)
v-icon
chevron_
right
v-flex
(xs6)
v-icon
mdi-chevron-
right
v-flex
v-card.editor-markdown-help-result(flat)
v-card-text
img(src='https://via.placeholder.com/150x50.png')
...
...
@@ -113,7 +113,7 @@
v-card-text
.d-flex
v-toolbar.radius-7(color='teal lighten-5', dense, flat, height='44')
v-icon.mr-3(color='teal')
info
v-icon.mr-3(color='teal')
mdi-information-variant
.body-2.teal--text Markdown Reference (continued)
.body-2.mt-3 Links
v-layout(row)
...
...
@@ -121,8 +121,8 @@
v-card.editor-markdown-help-source(flat)
v-card-text
div [Link Text](https://wiki.js.org)
v-icon
chevron_
right
v-flex
(xs6)
v-icon
mdi-chevron-
right
v-flex
v-card.editor-markdown-help-result(flat)
v-card-text
.caption: a(href='https://wiki.js.org', target='_blank') Link Text
...
...
@@ -132,8 +132,8 @@
v-card.editor-markdown-help-source(flat)
v-card-text
div Lorem ^ipsum^
v-icon
chevron_
right
v-flex
(xs6)
v-icon
mdi-chevron-
right
v-flex
v-card.editor-markdown-help-result(flat)
v-card-text
.caption Lorem #[sup ipsum]
...
...
@@ -143,8 +143,8 @@
v-card.editor-markdown-help-source(flat)
v-card-text
div Lorem ~ipsum~
v-icon
chevron_
right
v-flex
(xs6)
v-icon
mdi-chevron-
right
v-flex
v-card.editor-markdown-help-result(flat)
v-card-text
.caption: em Lorem #[sub ipsum]
...
...
@@ -156,8 +156,8 @@
div Lorem ipsum
div ---
div Dolor sit amet
v-icon
chevron_
right
v-flex
(xs6)
v-icon
mdi-chevron-
right
v-flex
v-card.editor-markdown-help-result(flat)
v-card-text
.caption Lorem ipsum
...
...
@@ -169,8 +169,8 @@
v-card.editor-markdown-help-source(flat)
v-card-text
div Lorem `ipsum dolor sit` amet
v-icon
chevron_
right
v-flex
(xs6)
v-icon
mdi-chevron-
right
v-flex
v-card.editor-markdown-help-result(flat)
v-card-text
.caption Lorem #[code ipsum dolor sit] amet
...
...
@@ -185,8 +185,8 @@
div.pl-3 echo 'Lorem ipsum'
div }
div ```
v-icon
chevron_
right
v-flex
(xs6)
v-icon
mdi-chevron-
right
v-flex
v-card.editor-markdown-help-result(flat)
v-card-text.contents
pre.prismjs.line-numbers.language-js
...
...
@@ -211,8 +211,8 @@
div > Lorem ipsum
div > dolor sit amet
div > consectetur adipiscing elit
v-icon
chevron_
right
v-flex
(xs6)
v-icon
mdi-chevron-
right
v-flex
v-card.editor-markdown-help-result(flat)
v-card-text
blockquote(style='border: 1px solid #263238; border-radius: .5rem; padding: 1rem 24px;') Lorem ipsum#[br]dolor sit amet#[br]consectetur adipiscing elit
...
...
@@ -221,7 +221,7 @@
v-card.radius-7.animated.fadeInUp.wait-p2s(light)
v-card-text
v-toolbar.radius-7(color='teal lighten-5', dense, flat)
v-icon.mr-3(color='teal') keyboard
v-icon.mr-3(color='teal')
mdi-
keyboard
.body-2.teal--text Keyboard Shortcuts
v-list.editor-markdown-help-kbd(two-line, dense)
v-list-item
...
...
@@ -255,13 +255,13 @@
v-list-item
v-list-item-content
v-list-item-title.body-2 Distraction Free Mode
v-list-item-sub
-
title Press <kbd>Esc</kbd> to exit.
v-list-item-subtitle Press <kbd>Esc</kbd> to exit.
v-list-item-action #[kbd F11]
v-card.radius-7.animated.fadeInUp.wait-p3s.mt-3(light)
v-card-text
v-toolbar.radius-7(color='teal lighten-5', dense, flat)
v-icon.mr-3(color='teal') mouse
v-icon.mr-3(color='teal') m
di-m
ouse
.body-2.teal--text Multi-Selection
v-list.editor-markdown-help-kbd(two-line, dense)
v-list-item
...
...
@@ -303,6 +303,10 @@ export default {
font-family
:
'Roboto Mono'
,
monospace
;
font-size
:
14px
;
color
:
#FFF
!
important
;
.v-card__text
{
color
:
#FFF
!
important
;
}
}
&
-result
{
...
...
@@ -327,7 +331,7 @@ export default {
}
&
-kbd
{
.v-list
__tile
__action
{
.v-list
-item
__action
{
flex-direction
:
row
;
align-items
:
center
;
...
...
@@ -345,12 +349,5 @@ export default {
}
}
}
&
-ref
{
.v-list__tile__action
{
flex-direction
:
row
;
align-items
:
center
;
}
}
}
</
style
>
client/components/login.vue
View file @
2d2cf905
...
...
@@ -109,7 +109,7 @@
v
-
spacer
template
(
v
-
if
=
'screen === "login" && isSocialShown'
)
v
-
divider
v
-
card
-
text
.
grey
.
lighten
-
4
.
text
-
xs
-
center
v
-
card
-
text
.
grey
.
lighten
-
4
.
text
-
center
.
pb
-
2
.
body
-
2
.
text
-
xs
-
center
.
grey
--
text
.
text
--
darken
-
2
{{
$t
(
'auth:orLoginUsingStrategy'
)
}}
v
-
tooltip
(
top
,
v
-
for
=
'strategy in strategies'
,
:
key
=
'strategy.key'
)
.
social
-
login
-
btn
.
mr
-
2
(
...
...
client/scss/components/v-data-table.scss
View file @
2d2cf905
.v-datatable
{
.v-data
-
table
{
.is-clickable
{
cursor
:
pointer
;
}
...
...
server/graph/resolvers/user.js
View file @
2d2cf905
const
graphHelper
=
require
(
'../../helpers/graph'
)
/* global WIKI */
...
...
@@ -28,8 +29,16 @@ module.exports = {
}
},
UserMutation
:
{
create
(
obj
,
args
)
{
return
WIKI
.
models
.
users
.
createNewUser
(
args
)
async
create
(
obj
,
args
)
{
try
{
await
WIKI
.
models
.
users
.
createNewUser
(
args
)
return
{
responseResult
:
graphHelper
.
generateSuccess
(
'User created successfully'
)
}
}
catch
(
err
)
{
return
graphHelper
.
generateError
(
err
)
}
},
delete
(
obj
,
args
)
{
return
WIKI
.
models
.
users
.
query
().
deleteById
(
args
.
id
)
...
...
server/models/users.js
View file @
2d2cf905
...
...
@@ -180,6 +180,20 @@ module.exports = class User extends Model {
}
primaryEmail
=
_
.
toLower
(
primaryEmail
)
// Find pending social user
if
(
!
user
)
{
user
=
await
WIKI
.
models
.
users
.
query
().
findOne
({
email
:
primaryEmail
,
providerId
:
null
,
providerKey
})
if
(
user
)
{
user
=
await
user
.
$query
().
patchAndFetch
({
providerId
:
_
.
toString
(
profile
.
id
)
})
}
}
// Parse display name
let
displayName
=
''
if
(
_
.
isString
(
profile
.
displayName
)
&&
profile
.
displayName
.
length
>
0
)
{
...
...
@@ -365,35 +379,60 @@ module.exports = class User extends Model {
email
=
_
.
toLower
(
email
)
// Input validation
const
validation
=
validate
({
email
,
passwordRaw
,
name
},
{
email
:
{
email
:
true
,
length
:
{
maximum
:
255
}
},
passwordRaw
:
{
presence
:
{
allowEmpty
:
false
let
validation
=
null
if
(
providerKey
===
'local'
)
{
validation
=
validate
({
email
,
passwordRaw
,
name
},
{
email
:
{
email
:
true
,
length
:
{
maximum
:
255
}
},
length
:
{
minimum
:
6
passwordRaw
:
{
presence
:
{
allowEmpty
:
false
},
length
:
{
minimum
:
6
}
},
name
:
{
presence
:
{
allowEmpty
:
false
},
length
:
{
minimum
:
2
,
maximum
:
255
}
}
},
name
:
{
presence
:
{
allowEmpty
:
false
},
{
format
:
'flat'
})
}
else
{
validation
=
validate
({
email
,
name
},
{
email
:
{
email
:
true
,
length
:
{
maximum
:
255
}
},
length
:
{
minimum
:
2
,
maximum
:
255
name
:
{
presence
:
{
allowEmpty
:
false
},
length
:
{
minimum
:
2
,
maximum
:
255
}
}
}
},
{
format
:
'flat'
})
},
{
format
:
'flat'
})
}
if
(
validation
&&
validation
.
length
>
0
)
{
throw
new
WIKI
.
Error
.
InputInvalid
(
validation
[
0
])
}
...
...
@@ -402,19 +441,25 @@ module.exports = class User extends Model {
const
usr
=
await
WIKI
.
models
.
users
.
query
().
findOne
({
email
,
providerKey
})
if
(
!
usr
)
{
// Create the account
const
newUsr
=
await
WIKI
.
models
.
users
.
query
().
insert
(
{
provider
:
provider
Key
,
let
newUsrData
=
{
providerKey
,
email
,
name
,
password
:
passwordRaw
,
locale
:
'en'
,
defaultEditor
:
'markdown'
,
tfaIsActive
:
false
,
isSystem
:
false
,
isActive
:
true
,
isVerified
:
true
,
mustChangePwd
:
(
mustChangePassword
===
true
)
})
mustChangePwd
:
false
}
if
(
providerKey
===
`local`
)
{
newUsrData
.
password
=
passwordRaw
newUsrData
.
mustChangePwd
=
(
mustChangePassword
===
true
)
}
const
newUsr
=
await
WIKI
.
models
.
users
.
query
().
insert
(
newUsrData
)
// Assign to group(s)
if
(
groups
.
length
>
0
)
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment