feat: GraphQL translations + login form
This commit is contained in:
@@ -11,6 +11,7 @@ const AzureAdOAuth2Strategy = require('passport-azure-ad-oauth2').Strategy
|
||||
module.exports = {
|
||||
key: 'azure',
|
||||
title: 'Azure Active Directory',
|
||||
useForm: false,
|
||||
props: ['clientId', 'clientSecret', 'callbackURL', 'resource', 'tenant'],
|
||||
init (passport, conf) {
|
||||
const jwt = require('jsonwebtoken')
|
||||
|
@@ -11,6 +11,7 @@ const FacebookStrategy = require('passport-facebook').Strategy
|
||||
module.exports = {
|
||||
key: 'facebook',
|
||||
title: 'Facebook',
|
||||
useForm: false,
|
||||
props: ['clientId', 'clientSecret', 'callbackURL'],
|
||||
init (passport, conf) {
|
||||
passport.use('facebook',
|
||||
|
@@ -11,6 +11,7 @@ const GitHubStrategy = require('passport-github2').Strategy
|
||||
module.exports = {
|
||||
key: 'github',
|
||||
title: 'GitHub',
|
||||
useForm: false,
|
||||
props: ['clientId', 'clientSecret', 'callbackURL'],
|
||||
init (passport, conf) {
|
||||
passport.use('github',
|
||||
|
@@ -11,6 +11,7 @@ const GoogleStrategy = require('passport-google-oauth20').Strategy
|
||||
module.exports = {
|
||||
key: 'google',
|
||||
title: 'Google ID',
|
||||
useForm: false,
|
||||
props: ['clientId', 'clientSecret', 'callbackURL'],
|
||||
init (passport, conf) {
|
||||
passport.use('google',
|
||||
|
@@ -12,6 +12,7 @@ const fs = require('fs')
|
||||
module.exports = {
|
||||
key: 'ldap',
|
||||
title: 'LDAP / Active Directory',
|
||||
useForm: true,
|
||||
props: ['url', 'bindDn', 'bindCredentials', 'searchBase', 'searchFilter', 'tlsEnabled', 'tlsCertPath'],
|
||||
init (passport, conf) {
|
||||
passport.use('ldapauth',
|
||||
|
@@ -11,6 +11,7 @@ const LocalStrategy = require('passport-local').Strategy
|
||||
module.exports = {
|
||||
key: 'local',
|
||||
title: 'Local',
|
||||
useForm: true,
|
||||
props: [],
|
||||
init (passport, conf) {
|
||||
passport.use('local',
|
||||
|
@@ -11,6 +11,7 @@ const WindowsLiveStrategy = require('passport-windowslive').Strategy
|
||||
module.exports = {
|
||||
key: 'microsoft',
|
||||
title: 'Microsoft Account',
|
||||
useForm: false,
|
||||
props: ['clientId', 'clientSecret', 'callbackURL'],
|
||||
init (passport, conf) {
|
||||
passport.use('windowslive',
|
||||
|
@@ -11,6 +11,7 @@ const SlackStrategy = require('passport-slack').Strategy
|
||||
module.exports = {
|
||||
key: 'slack',
|
||||
title: 'Slack',
|
||||
useForm: false,
|
||||
props: ['clientId', 'clientSecret', 'callbackURL'],
|
||||
init (passport, conf) {
|
||||
passport.use('slack',
|
||||
|
@@ -20,7 +20,7 @@ module.exports = Promise.join(
|
||||
wiki.disk = require('./modules/disk').init()
|
||||
wiki.docs = require('./modules/documents').init()
|
||||
wiki.git = require('./modules/git').init(false)
|
||||
wiki.lang = require('i18next')
|
||||
wiki.lang = require('./modules/localization').init()
|
||||
wiki.mark = require('./modules/markdown')
|
||||
wiki.search = require('./modules/search').init()
|
||||
wiki.upl = require('./modules/uploads').init()
|
||||
@@ -37,13 +37,10 @@ module.exports = Promise.join(
|
||||
const favicon = require('serve-favicon')
|
||||
const flash = require('connect-flash')
|
||||
const http = require('http')
|
||||
const i18nBackend = require('i18next-node-fs-backend')
|
||||
const path = require('path')
|
||||
const passportSocketIo = require('passport.socketio')
|
||||
const session = require('express-session')
|
||||
const SessionRedisStore = require('connect-redis')(session)
|
||||
const graceful = require('node-graceful')
|
||||
const socketio = require('socket.io')
|
||||
const graphqlApollo = require('apollo-server-express')
|
||||
const graphqlSchema = require('./modules/graphql')
|
||||
|
||||
@@ -100,23 +97,6 @@ module.exports = Promise.join(
|
||||
|
||||
app.use(mw.seo)
|
||||
|
||||
// ----------------------------------------
|
||||
// Localization Engine
|
||||
// ----------------------------------------
|
||||
|
||||
wiki.lang.use(i18nBackend).init({
|
||||
load: 'languageOnly',
|
||||
ns: ['common', 'admin', 'auth', 'errors', 'git'],
|
||||
defaultNS: 'common',
|
||||
saveMissing: false,
|
||||
preload: [wiki.config.site.lang],
|
||||
lng: wiki.config.site.lang,
|
||||
fallbackLng: 'en',
|
||||
backend: {
|
||||
loadPath: path.join(wiki.SERVERPATH, 'locales/{{lng}}/{{ns}}.json')
|
||||
}
|
||||
})
|
||||
|
||||
// ----------------------------------------
|
||||
// View Engine Setup
|
||||
// ----------------------------------------
|
||||
@@ -133,7 +113,7 @@ module.exports = Promise.join(
|
||||
|
||||
app.locals.basedir = wiki.ROOTPATH
|
||||
app.locals._ = require('lodash')
|
||||
app.locals.t = wiki.lang.t.bind(wiki.lang)
|
||||
app.locals.t = wiki.lang.engine.t.bind(wiki.lang)
|
||||
app.locals.moment = require('moment')
|
||||
app.locals.moment.locale(wiki.config.site.lang)
|
||||
app.locals.config = wiki.config
|
||||
@@ -173,11 +153,10 @@ module.exports = Promise.join(
|
||||
// Start HTTP server
|
||||
// ----------------------------------------
|
||||
|
||||
wiki.logger.info(`HTTP/WS Server on port: ${wiki.config.port}`)
|
||||
wiki.logger.info(`HTTP Server on port: ${wiki.config.port}`)
|
||||
|
||||
app.set('port', wiki.config.port)
|
||||
var server = http.createServer(app)
|
||||
var io = socketio(server)
|
||||
let server = http.createServer(app)
|
||||
|
||||
server.listen(wiki.config.port)
|
||||
server.on('error', (error) => {
|
||||
@@ -199,35 +178,14 @@ module.exports = Promise.join(
|
||||
})
|
||||
|
||||
server.on('listening', () => {
|
||||
wiki.logger.info('HTTP/WS Server: RUNNING')
|
||||
wiki.logger.info('HTTP Server: RUNNING')
|
||||
})
|
||||
|
||||
// ----------------------------------------
|
||||
// WebSocket
|
||||
// ----------------------------------------
|
||||
|
||||
io.use(passportSocketIo.authorize({
|
||||
key: 'wikijs.sid',
|
||||
store: sessionStore,
|
||||
secret: wiki.config.site.sessionSecret,
|
||||
cookieParser,
|
||||
success: (data, accept) => {
|
||||
accept()
|
||||
},
|
||||
fail: (data, message, error, accept) => {
|
||||
accept()
|
||||
}
|
||||
}))
|
||||
|
||||
io.on('connection', ctrl.ws)
|
||||
|
||||
// ----------------------------------------
|
||||
// Graceful shutdown
|
||||
// ----------------------------------------
|
||||
|
||||
graceful.on('exit', () => {
|
||||
// wiki.logger.info('- SHUTTING DOWN - Terminating Background Agent...')
|
||||
// bgAgent.kill()
|
||||
wiki.logger.info('- SHUTTING DOWN - Performing git sync...')
|
||||
return global.git.resync().then(() => {
|
||||
wiki.logger.info('- SHUTTING DOWN - Git sync successful. Now safe to exit.')
|
||||
|
@@ -17,6 +17,7 @@ const FolderResolvers = require('../schemas/resolvers-folder')
|
||||
const GroupResolvers = require('../schemas/resolvers-group')
|
||||
const SettingResolvers = require('../schemas/resolvers-setting')
|
||||
const TagResolvers = require('../schemas/resolvers-tag')
|
||||
const TranslationResolvers = require('../schemas/resolvers-translation')
|
||||
const UserResolvers = require('../schemas/resolvers-user')
|
||||
|
||||
const resolvers = _.merge(
|
||||
@@ -27,6 +28,7 @@ const resolvers = _.merge(
|
||||
GroupResolvers,
|
||||
SettingResolvers,
|
||||
TagResolvers,
|
||||
TranslationResolvers,
|
||||
UserResolvers,
|
||||
DateScalar
|
||||
)
|
||||
|
52
server/modules/localization.js
Normal file
52
server/modules/localization.js
Normal file
@@ -0,0 +1,52 @@
|
||||
const _ = require('lodash')
|
||||
const dotize = require('dotize')
|
||||
const i18nBackend = require('i18next-node-fs-backend')
|
||||
const i18next = require('i18next')
|
||||
const path = require('path')
|
||||
const Promise = require('bluebird')
|
||||
|
||||
/* global wiki */
|
||||
|
||||
module.exports = {
|
||||
engine: null,
|
||||
namespaces: ['common', 'admin', 'auth', 'errors', 'git'],
|
||||
init() {
|
||||
this.engine = i18next
|
||||
this.engine.use(i18nBackend).init({
|
||||
load: 'languageOnly',
|
||||
ns: this.namespaces,
|
||||
defaultNS: 'common',
|
||||
saveMissing: false,
|
||||
preload: [wiki.config.site.lang],
|
||||
lng: wiki.config.site.lang,
|
||||
fallbackLng: 'en',
|
||||
backend: {
|
||||
loadPath: path.join(wiki.SERVERPATH, 'locales/{{lng}}/{{ns}}.json')
|
||||
}
|
||||
})
|
||||
return this
|
||||
},
|
||||
getByNamespace(locale, namespace) {
|
||||
if (this.engine.hasResourceBundle(locale, namespace)) {
|
||||
let data = this.engine.getResourceBundle(locale, namespace)
|
||||
return _.map(dotize.convert(data), (value, key) => {
|
||||
return {
|
||||
key,
|
||||
value
|
||||
}
|
||||
})
|
||||
} else {
|
||||
throw new Error('Invalid locale or namespace')
|
||||
}
|
||||
},
|
||||
loadLocale(locale) {
|
||||
return Promise.fromCallback(cb => {
|
||||
return this.engine.loadLanguages(locale, cb)
|
||||
})
|
||||
},
|
||||
setCurrentLocale(locale) {
|
||||
return Promise.fromCallback(cb => {
|
||||
return this.engine.changeLanguage(locale, cb)
|
||||
})
|
||||
}
|
||||
}
|
@@ -1,4 +1,3 @@
|
||||
'use strict'
|
||||
|
||||
/* global wiki */
|
||||
|
||||
|
@@ -1,4 +1,3 @@
|
||||
'use strict'
|
||||
|
||||
/* global wiki */
|
||||
|
||||
|
@@ -1,4 +1,3 @@
|
||||
'use strict'
|
||||
|
||||
/* global wiki */
|
||||
|
||||
|
@@ -1,4 +1,3 @@
|
||||
'use strict'
|
||||
|
||||
/* global wiki */
|
||||
|
||||
|
@@ -1,4 +1,3 @@
|
||||
'use strict'
|
||||
|
||||
/* global wiki */
|
||||
|
||||
|
@@ -1,4 +1,3 @@
|
||||
'use strict'
|
||||
|
||||
/* global wiki */
|
||||
|
||||
|
@@ -1,4 +1,3 @@
|
||||
'use strict'
|
||||
|
||||
/* global wiki */
|
||||
|
||||
|
@@ -1,4 +1,3 @@
|
||||
'use strict'
|
||||
|
||||
/* global wiki */
|
||||
|
||||
|
12
server/schemas/resolvers-translation.js
Normal file
12
server/schemas/resolvers-translation.js
Normal file
@@ -0,0 +1,12 @@
|
||||
|
||||
/* global wiki */
|
||||
|
||||
module.exports = {
|
||||
Query: {
|
||||
translations (obj, args, context, info) {
|
||||
return wiki.lang.getByNamespace(args.locale, args.namespace)
|
||||
}
|
||||
},
|
||||
Mutation: {},
|
||||
Translation: {}
|
||||
}
|
@@ -1,4 +1,3 @@
|
||||
'use strict'
|
||||
|
||||
/* global wiki */
|
||||
|
||||
|
@@ -1,4 +1,3 @@
|
||||
'use strict'
|
||||
|
||||
const gql = require('graphql')
|
||||
|
||||
|
@@ -114,6 +114,11 @@ type Tag implements Base {
|
||||
documents: [Document]
|
||||
}
|
||||
|
||||
type Translation {
|
||||
key: String!
|
||||
value: String!
|
||||
}
|
||||
|
||||
# A User
|
||||
type User implements Base {
|
||||
id: Int!
|
||||
@@ -142,6 +147,7 @@ type Query {
|
||||
rights(id: Int): [Right]
|
||||
settings(key: String): [Setting]
|
||||
tags(key: String): [Tag]
|
||||
translations(locale: String!, namespace: String!): [Translation]
|
||||
users(id: Int, email: String, provider: String, providerId: String, role: UserRole): [User]
|
||||
}
|
||||
|
||||
|
@@ -2,31 +2,5 @@ extends ../master.pug
|
||||
|
||||
block body
|
||||
body
|
||||
.login#root(class={ "is-error": flash.length > 0 })
|
||||
.login-container(class={ "is-expanded": hasMultipleStrategies })
|
||||
if flash.length > 0
|
||||
.login-error
|
||||
strong
|
||||
i.icon-warning-outline
|
||||
= flash[0].title
|
||||
span= flash[0].message
|
||||
if hasMultipleStrategies
|
||||
.login-providers
|
||||
button.is-active(title=t('auth:providers.local'))
|
||||
i.nc-icon-outline.ui-1_database
|
||||
span= t('auth:providers.local')
|
||||
each strategy in authStrategies
|
||||
button(onclick='window.location.assign("/login/' + strategy.key + '")', title=strategy.title)
|
||||
!= strategy.icon
|
||||
span= strategy.title
|
||||
.login-frame
|
||||
h1= config.site.title
|
||||
h2= t('auth:loginrequired')
|
||||
form(method='post', action='/login')
|
||||
input#login-user(type='text', name='email', placeholder=t('auth:fields.emailuser'))
|
||||
input#login-pass(type='password', name='password', placeholder=t('auth:fields.password'))
|
||||
button.button.is-light-blue.is-fullwidth(type='submit')
|
||||
span= t('auth:actions.login')
|
||||
.login-copyright
|
||||
= t('footer.poweredby')
|
||||
a(href='https://wiki.js.org', rel='external', title='Wiki.js') Wiki.js
|
||||
#app.is-fullscreen
|
||||
login
|
||||
|
@@ -2,7 +2,7 @@ extends ./master.pug
|
||||
|
||||
block body
|
||||
body
|
||||
#root.has-stickynav(class=['is-primary-' + appconfig.theme.primary, 'is-alternate-' + appconfig.theme.alt])
|
||||
#app.has-stickynav(class=['is-primary-' + appconfig.theme.primary, 'is-alternate-' + appconfig.theme.alt])
|
||||
include ./common/header.pug
|
||||
alert
|
||||
main
|
||||
|
Reference in New Issue
Block a user