Commit 40d224e8 authored by Nick's avatar Nick

feat: admin mail - send test email

parent 17f9f0ba
...@@ -136,11 +136,11 @@ ...@@ -136,11 +136,11 @@
:label='$t(`admin:mail.testRecipient`)' :label='$t(`admin:mail.testRecipient`)'
:counter='255' :counter='255'
prepend-icon='mail' prepend-icon='mail'
disabled :disabled='testLoading'
) )
v-card-chin v-card-chin
v-spacer v-spacer
v-btn(color='teal', :dark='false', disabled) {{ $t('admin:mail.testSend') }} v-btn(color='teal', dark, @click='sendTest', :loading='testLoading') {{ $t('admin:mail.testSend') }}
</template> </template>
...@@ -149,6 +149,7 @@ import _ from 'lodash' ...@@ -149,6 +149,7 @@ import _ from 'lodash'
import { get } from 'vuex-pathify' import { get } from 'vuex-pathify'
import mailConfigQuery from 'gql/admin/mail/mail-query-config.gql' import mailConfigQuery from 'gql/admin/mail/mail-query-config.gql'
import mailUpdateConfigMutation from 'gql/admin/mail/mail-mutation-save-config.gql' import mailUpdateConfigMutation from 'gql/admin/mail/mail-mutation-save-config.gql'
import mailTestMutation from 'gql/admin/mail/mail-mutation-sendtest.gql'
export default { export default {
data() { data() {
...@@ -166,7 +167,8 @@ export default { ...@@ -166,7 +167,8 @@ export default {
dkimKeySelector: '', dkimKeySelector: '',
dkimPrivateKey: '' dkimPrivateKey: ''
}, },
testEmail: '' testEmail: '',
testLoading: false
} }
}, },
computed: { computed: {
...@@ -202,6 +204,31 @@ export default { ...@@ -202,6 +204,31 @@ export default {
} catch (err) { } catch (err) {
this.$store.commit('pushGraphError', err) this.$store.commit('pushGraphError', err)
} }
},
async sendTest () {
try {
const resp = await this.$apollo.mutate({
mutation: mailTestMutation,
variables: {
recipientEmail: this.testEmail
},
watchLoading (isLoading) {
this.$store.commit(`loading${isLoading ? 'Start' : 'Stop'}`, 'admin-mail-test')
}
})
if (!_.get(resp, 'data.mail.sendTest.responseResult.succeeded', false)) {
throw new Error(_.get(resp, 'data.mail.sendTest.responseResult.message', 'An unexpected error occured.'))
}
this.testEmail = ''
this.$store.commit('showNotification', {
style: 'success',
message: this.$t('admin:mail.sendTestSuccess'),
icon: 'check'
})
} catch (err) {
this.$store.commit('pushGraphError', err)
}
} }
}, },
apollo: { apollo: {
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
v-icon(left) add v-icon(left) add
span New Page span New Page
v-card.wiki-form.mt-3 v-card.wiki-form.mt-3
v-toolbar(flat, :color='$vuetify.dark ? `grey darken-3-d5` : `white`', height='80') v-toolbar(flat, :color='$vuetify.dark ? `grey darken-3-d5` : `grey lighten-5`', height='80')
v-spacer v-spacer
v-text-field( v-text-field(
outline outline
......
...@@ -64,8 +64,8 @@ ...@@ -64,8 +64,8 @@
v-card-chin v-card-chin
v-spacer v-spacer
v-btn(flat, @click='isShown = false') Cancel v-btn(flat, @click='isShown = false') Cancel
v-btn(color='primary', @click='newUser') Create v-btn(color='primary', @click='newUser(true)') Create
v-btn(color='primary', @click='newUser') Create and Close v-btn(color='primary', @click='newUser(false)') Create and Close
</template> </template>
<script> <script>
...@@ -111,7 +111,7 @@ export default { ...@@ -111,7 +111,7 @@ export default {
}, },
methods: { methods: {
async newUser() { async newUser() {
this.isShown = false
}, },
generatePwd() { generatePwd() {
this.password = uuidv4().slice(-12) this.password = uuidv4().slice(-12)
......
mutation ($recipientEmail: String!) {
mail {
sendTest(recipientEmail: $recipientEmail) {
responseResult {
succeeded
errorCode
slug
message
}
}
}
}
...@@ -44,7 +44,7 @@ module.exports = { ...@@ -44,7 +44,7 @@ module.exports = {
async send(opts) { async send(opts) {
if (!this.transport) { if (!this.transport) {
WIKI.logger.warn('Cannot send email because mail is not setup in the administration area!') WIKI.logger.warn('Cannot send email because mail is not setup in the administration area!')
throw new WIKI.Error.MailNotSetup() throw new WIKI.Error.MailNotConfigured()
} }
await this.loadTemplate(opts.template) await this.loadTemplate(opts.template)
return this.transport.sendMail({ return this.transport.sendMail({
......
...@@ -16,6 +16,29 @@ module.exports = { ...@@ -16,6 +16,29 @@ module.exports = {
} }
}, },
MailMutation: { MailMutation: {
async sendTest(obj, args, context) {
try {
if (_.isEmpty(args.recipientEmail) || args.recipientEmail.length < 6) {
throw new WIKI.Error.MailInvalidRecipient()
}
await WIKI.mail.send({
template: 'test',
to: args.recipientEmail,
subject: 'A test email from your wiki',
text: 'This is a test email sent from your wiki.',
data: {
preheadertext: 'This is a test email sent from your wiki.'
}
})
return {
responseResult: graphHelper.generateSuccess('Test email sent successfully.')
}
} catch (err) {
return graphHelper.generateError(err)
}
},
async updateConfig(obj, args, context) { async updateConfig(obj, args, context) {
try { try {
WIKI.config.mail = { WIKI.config.mail = {
...@@ -29,14 +52,14 @@ module.exports = { ...@@ -29,14 +52,14 @@ module.exports = {
useDKIM: args.useDKIM, useDKIM: args.useDKIM,
dkimDomainName: args.dkimDomainName, dkimDomainName: args.dkimDomainName,
dkimKeySelector: args.dkimKeySelector, dkimKeySelector: args.dkimKeySelector,
dkimPrivateKey: args.dkimPrivateKey, dkimPrivateKey: args.dkimPrivateKey
} }
await WIKI.configSvc.saveToDb(['mail']) await WIKI.configSvc.saveToDb(['mail'])
WIKI.mail.init() WIKI.mail.init()
return { return {
responseResult: graphHelper.generateSuccess('Mail configuration updated successfully') responseResult: graphHelper.generateSuccess('Mail configuration updated successfully.')
} }
} catch (err) { } catch (err) {
return graphHelper.generateError(err) return graphHelper.generateError(err)
......
...@@ -23,6 +23,10 @@ type MailQuery { ...@@ -23,6 +23,10 @@ type MailQuery {
# ----------------------------------------------- # -----------------------------------------------
type MailMutation { type MailMutation {
sendTest(
recipientEmail: String!
): DefaultResponse @auth(requires: ["manage:system"])
updateConfig( updateConfig(
senderName: String! senderName: String!
senderEmail: String! senderEmail: String!
......
...@@ -10,7 +10,7 @@ module.exports = { ...@@ -10,7 +10,7 @@ module.exports = {
code: 2002 code: 2002
}), }),
AssetGenericError: CustomError('AssetGenericError', { AssetGenericError: CustomError('AssetGenericError', {
message: 'An unexpected error occured during asset change.', message: 'An unexpected error occured during asset operation.',
code: 2001 code: 2001
}), }),
AssetInvalid: CustomError('AssetInvalid', { AssetInvalid: CustomError('AssetInvalid', {
...@@ -39,11 +39,15 @@ module.exports = { ...@@ -39,11 +39,15 @@ module.exports = {
}), }),
AuthAccountBanned: CustomError('AuthAccountBanned', { AuthAccountBanned: CustomError('AuthAccountBanned', {
message: 'Your account has been disabled.', message: 'Your account has been disabled.',
code: 1016 code: 1013
}),
AuthAccountAlreadyExists: CustomError('AuthAccountAlreadyExists', {
message: 'An account already exists using this email address.',
code: 1004
}), }),
AuthAccountNotVerified: CustomError('AuthAccountNotVerified', { AuthAccountNotVerified: CustomError('AuthAccountNotVerified', {
message: 'You must verify your account before your can login.', message: 'You must verify your account before your can login.',
code: 1017 code: 1014
}), }),
AuthGenericError: CustomError('AuthGenericError', { AuthGenericError: CustomError('AuthGenericError', {
message: 'An unexpected error occured during login.', message: 'An unexpected error occured during login.',
...@@ -57,17 +61,13 @@ module.exports = { ...@@ -57,17 +61,13 @@ module.exports = {
message: 'Invalid authentication provider.', message: 'Invalid authentication provider.',
code: 1003 code: 1003
}), }),
AuthAccountAlreadyExists: CustomError('AuthAccountAlreadyExists', {
message: 'An account already exists using this email address.',
code: 1004
}),
AuthRegistrationDisabled: CustomError('AuthRegistrationDisabled', { AuthRegistrationDisabled: CustomError('AuthRegistrationDisabled', {
message: 'Registration is disabled. Contact your system administrator.', message: 'Registration is disabled. Contact your system administrator.',
code: 1011 code: 1010
}), }),
AuthRegistrationDomainUnauthorized: CustomError('AuthRegistrationDomainUnauthorized', { AuthRegistrationDomainUnauthorized: CustomError('AuthRegistrationDomainUnauthorized', {
message: 'You are not authorized to register. Must use a whitelisted domain.', message: 'You are not authorized to register. Your domain is not whitelisted.',
code: 1012 code: 1011
}), }),
AuthTFAFailed: CustomError('AuthTFAFailed', { AuthTFAFailed: CustomError('AuthTFAFailed', {
message: 'Incorrect TFA Security Code.', message: 'Incorrect TFA Security Code.',
...@@ -79,7 +79,7 @@ module.exports = { ...@@ -79,7 +79,7 @@ module.exports = {
}), }),
AuthValidationTokenInvalid: CustomError('AuthValidationTokenInvalid', { AuthValidationTokenInvalid: CustomError('AuthValidationTokenInvalid', {
message: 'Invalid validation token.', message: 'Invalid validation token.',
code: 1018 code: 1015
}), }),
BruteInstanceIsInvalid: CustomError('BruteInstanceIsInvalid', { BruteInstanceIsInvalid: CustomError('BruteInstanceIsInvalid', {
message: 'Invalid Brute Force Instance.', message: 'Invalid Brute Force Instance.',
...@@ -91,26 +91,42 @@ module.exports = { ...@@ -91,26 +91,42 @@ module.exports = {
}), }),
InputInvalid: CustomError('InputInvalid', { InputInvalid: CustomError('InputInvalid', {
message: 'Input data is invalid.', message: 'Input data is invalid.',
code: 1013 code: 1012
}),
MailNotSetup: CustomError('MailNotSetup', {
message: 'Mail is not setup yet.',
code: 1014
}), }),
MailTemplateFailed: CustomError('MailTemplateFailed', { LocaleGenericError: CustomError('LocaleGenericError', {
message: 'Mail template failed to load.', message: 'An unexpected error occured during locale operation.',
code: 1015 code: 5001
}), }),
LocaleInvalidNamespace: CustomError('LocaleInvalidNamespace', { LocaleInvalidNamespace: CustomError('LocaleInvalidNamespace', {
message: 'Invalid locale or namespace.', message: 'Invalid locale or namespace.',
code: 1009 code: 5002
}),
MailGenericError: CustomError('MailGenericError', {
message: 'An unexpected error occured during mail operation.',
code: 3001
}),
MailInvalidRecipient: CustomError('MailInvalidRecipient', {
message: 'The recipient email address is invalid.',
code: 3004
}),
MailNotConfigured: CustomError('MailNotConfigured', {
message: 'The mail configuration is incomplete or invalid.',
code: 3002
}),
MailTemplateFailed: CustomError('MailTemplateFailed', {
message: 'Mail template failed to load.',
code: 3003
}), }),
SearchActivationFailed: CustomError('SearchActivationFailed', { SearchActivationFailed: CustomError('SearchActivationFailed', {
message: 'Search Engine activation failed.', message: 'Search Engine activation failed.',
code: 1019 code: 4002
}),
SearchGenericError: CustomError('SearchGenericError', {
message: 'An unexpected error occured during search operation.',
code: 4001
}), }),
UserCreationFailed: CustomError('UserCreationFailed', { UserCreationFailed: CustomError('UserCreationFailed', {
message: 'An unexpected error occured during user creation.', message: 'An unexpected error occured during user creation.',
code: 1010 code: 1009
}) })
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment