diff --git a/server/db/migrations/3.0.0.js b/server/db/migrations/3.0.0.js
index ae3f90a2..0ac87fc8 100644
--- a/server/db/migrations/3.0.0.js
+++ b/server/db/migrations/3.0.0.js
@@ -63,13 +63,11 @@ exports.up = async knex => {
table.uuid('id').notNullable().primary().defaultTo(knex.raw('gen_random_uuid()'))
table.string('module').notNullable()
table.boolean('isEnabled').notNullable().defaultTo(false)
- table.integer('order').unsigned().notNullable().defaultTo(0)
table.string('displayName').notNullable().defaultTo('')
table.jsonb('config').notNullable().defaultTo('{}')
table.boolean('selfRegistration').notNullable().defaultTo(false)
table.jsonb('domainWhitelist').notNullable().defaultTo('[]')
table.jsonb('autoEnrollGroups').notNullable().defaultTo('[]')
- table.jsonb('hideOnSites').notNullable().defaultTo('[]')
})
.createTable('commentProviders', table => {
table.uuid('id').notNullable().primary().defaultTo(knex.raw('gen_random_uuid()'))
diff --git a/server/graph/resolvers/authentication.js b/server/graph/resolvers/authentication.js
index 93752ffb..a3661a8a 100644
--- a/server/graph/resolvers/authentication.js
+++ b/server/graph/resolvers/authentication.js
@@ -31,18 +31,18 @@ module.exports = {
async authStrategies () {
return WIKI.data.authentication.map(stg => ({
...stg,
- isAvailable: stg.isAvailable === true,
- props: _.sortBy(_.transform(stg.props, (res, value, key) => {
- res.push({
- key,
- value: JSON.stringify(value)
- })
- }, []), 'key')
+ isAvailable: stg.isAvailable === true
}))
},
/**
* Fetch active authentication strategies
*/
+ async authActiveStrategies (obj, args, context) {
+ return WIKI.models.authentication.getStrategies()
+ },
+ /**
+ * Fetch site authentication strategies
+ */
async authSiteStrategies (obj, args, context, info) {
let strategies = await WIKI.models.authentication.getStrategies()
strategies = strategies.map(stg => {
@@ -268,14 +268,9 @@ module.exports = {
}
}
},
- AuthenticationStrategy: {
- icon (ap, args) {
- return fs.readFile(path.join(WIKI.ROOTPATH, `assets/svg/auth-icon-${ap.key}.svg`), 'utf8').catch(err => {
- if (err.code === 'ENOENT') {
- return null
- }
- throw err
- })
+ AuthenticationActiveStrategy: {
+ strategy (obj, args, context) {
+ return _.find(WIKI.data.authentication, ['key', obj.module])
}
}
}
diff --git a/server/graph/schemas/authentication.graphql b/server/graph/schemas/authentication.graphql
index 22acf85f..9549a02d 100644
--- a/server/graph/schemas/authentication.graphql
+++ b/server/graph/schemas/authentication.graphql
@@ -9,9 +9,11 @@ extend type Query {
authStrategies: [AuthenticationStrategy]
+ authActiveStrategies: [AuthenticationActiveStrategy]
+
authSiteStrategies(
siteId: UUID!
- enabledOnly: Boolean
+ visibleOnly: Boolean
): [AuthenticationSiteStrategy]
}
@@ -73,7 +75,7 @@ extend type Mutation {
type AuthenticationStrategy {
key: String
- props: [KeyValuePair]
+ props: JSON
title: String
description: String
isAvailable: Boolean
@@ -81,22 +83,29 @@ type AuthenticationStrategy {
usernameType: String
logo: String
color: String
+ vendor: String
website: String
icon: String
}
-type AuthenticationSiteStrategy {
- key: String
+type AuthenticationActiveStrategy {
+ id: UUID
strategy: AuthenticationStrategy
displayName: String
- order: Int
isEnabled: Boolean
- config: [KeyValuePair]
+ config: JSON
selfRegistration: Boolean
domainWhitelist: [String]
autoEnrollGroups: [Int]
}
+type AuthenticationSiteStrategy {
+ id: UUID
+ activeStrategy: AuthenticationActiveStrategy
+ order: Int
+ isVisible: Boolean
+}
+
type AuthenticationLoginResponse {
operation: Operation
jwt: String
diff --git a/server/helpers/common.js b/server/helpers/common.js
index e2a38a35..44fd39f1 100644
--- a/server/helpers/common.js
+++ b/server/helpers/common.js
@@ -29,11 +29,12 @@ module.exports = {
default: defaultValue,
type: (value.type || value).toLowerCase(),
title: value.title || _.startCase(key),
- hint: value.hint || false,
+ hint: value.hint || '',
enum: value.enum || false,
+ enumDisplay: value.enumDisplay || 'select',
multiline: value.multiline || false,
sensitive: value.sensitive || false,
- maxWidth: value.maxWidth || 0,
+ icon: value.icon || 'rename',
order: value.order || 100
})
return result
diff --git a/server/models/authentication.js b/server/models/authentication.js
index ba6b49d4..6f596ad0 100644
--- a/server/models/authentication.js
+++ b/server/models/authentication.js
@@ -51,13 +51,14 @@ module.exports = class Authentication extends Model {
for (const dir of authenticationDirs) {
const def = await fs.readFile(path.join(WIKI.SERVERPATH, 'modules/authentication', dir, 'definition.yml'), 'utf8')
const defParsed = yaml.load(def)
+ if (!defParsed.isAvailable) { continue }
defParsed.key = dir
defParsed.props = commonHelper.parseModuleProps(defParsed.props)
- WIKI.data.analytics.push(defParsed)
+ WIKI.data.authentication.push(defParsed)
WIKI.logger.debug(`Loaded authentication module definition ${dir}: [ OK ]`)
}
- WIKI.logger.info(`Loaded ${WIKI.data.analytics.length} authentication module definitions: [ OK ]`)
+ WIKI.logger.info(`Loaded ${WIKI.data.authentication.length} authentication module definitions: [ OK ]`)
} catch (err) {
WIKI.logger.error(`Failed to scan or load authentication providers: [ FAILED ]`)
WIKI.logger.error(err)
diff --git a/server/modules/authentication/auth0/definition.yml b/server/modules/authentication/auth0/definition.yml
index 9f475181..54a701cb 100644
--- a/server/modules/authentication/auth0/definition.yml
+++ b/server/modules/authentication/auth0/definition.yml
@@ -3,6 +3,7 @@ title: Auth0
description: Auth0 provides universal identity platform for web, mobile, IoT, and internal applications.
author: requarks.io
logo: https://static.requarks.io/logo/auth0.svg
+icon: /_assets/icons/ultraviolet-auth0.svg
color: deep-orange
website: https://auth0.com/
isAvailable: true
diff --git a/server/modules/authentication/azure/definition.yml b/server/modules/authentication/azure/definition.yml
index ad7d41eb..f213b3c7 100644
--- a/server/modules/authentication/azure/definition.yml
+++ b/server/modules/authentication/azure/definition.yml
@@ -1,8 +1,9 @@
key: azure
title: Azure Active Directory
-description: Azure Active Directory (Azure AD) is Microsoft’s multi-tenant, cloud-based directory, and identity management service that combines core directory services, application access management, and identity protection into a single solution.
+description: Azure Active Directory (Azure AD) is Microsoft's multi-tenant, cloud-based directory, and identity management service that combines core directory services, application access management, and identity protection into a single solution.
author: requarks.io
logo: https://static.requarks.io/logo/azure.svg
+icon: /_assets/icons/ultraviolet-azure.svg
color: blue darken-3
website: https://azure.microsoft.com/services/active-directory/
isAvailable: true
diff --git a/server/modules/authentication/cas/definition.yml b/server/modules/authentication/cas/definition.yml
index 912840eb..35b423d7 100644
--- a/server/modules/authentication/cas/definition.yml
+++ b/server/modules/authentication/cas/definition.yml
@@ -3,6 +3,7 @@ title: CAS
description: The Central Authentication Service (CAS) is a single sign-on protocol for the web.
author: requarks.io
logo: https://static.requarks.io/logo/cas.svg
+icon: /_assets/icons/ultraviolet-cas.svg
color: green darken-2
website: https://apereo.github.io/cas/
useForm: false
diff --git a/server/modules/authentication/discord/definition.yml b/server/modules/authentication/discord/definition.yml
index e30becba..1d0e517d 100644
--- a/server/modules/authentication/discord/definition.yml
+++ b/server/modules/authentication/discord/definition.yml
@@ -3,6 +3,7 @@ title: Discord
description: Discord is a proprietary freeware VoIP application designed for gaming communities, that specializes in text, video and audio communication between users in a chat channel.
author: requarks.io
logo: https://static.requarks.io/logo/discord.svg
+icon: /_assets/icons/ultraviolet-discord.svg
color: indigo lighten-2
website: https://discord.com/
isAvailable: true
diff --git a/server/modules/authentication/dropbox/definition.yml b/server/modules/authentication/dropbox/definition.yml
index 9fc8ce05..11ea43ce 100644
--- a/server/modules/authentication/dropbox/definition.yml
+++ b/server/modules/authentication/dropbox/definition.yml
@@ -3,6 +3,7 @@ title: Dropbox
description: Dropbox is a file hosting service that offers cloud storage, file synchronization, personal cloud, and client software.
author: requarks.io
logo: https://static.requarks.io/logo/dropbox.svg
+icon: /_assets/icons/ultraviolet-dropbox.svg
color: blue darken-2
website: https://dropbox.com
isAvailable: true
diff --git a/server/modules/authentication/facebook/definition.yml b/server/modules/authentication/facebook/definition.yml
index 90bd7e20..fc0e668c 100644
--- a/server/modules/authentication/facebook/definition.yml
+++ b/server/modules/authentication/facebook/definition.yml
@@ -3,6 +3,7 @@ title: Facebook
description: Facebook is an online social media and social networking service company.
author: requarks.io
logo: https://static.requarks.io/logo/facebook.svg
+icon: /_assets/icons/ultraviolet-facebook.svg
color: indigo
website: https://facebook.com/
isAvailable: true
diff --git a/server/modules/authentication/firebase/authentication.js b/server/modules/authentication/firebase/authentication.js
deleted file mode 100644
index 344cd8e3..00000000
--- a/server/modules/authentication/firebase/authentication.js
+++ /dev/null
@@ -1,36 +0,0 @@
-/* global WIKI */
-
-// ------------------------------------
-// Firebase Account
-// ------------------------------------
-
-// INCOMPLETE / TODO
-
-const FirebaseStrategy = require('passport-github2').Strategy
-const _ = require('lodash')
-
-module.exports = {
- init (passport, conf) {
- passport.use(conf.key,
- new FirebaseStrategy({
- clientID: conf.clientId,
- clientSecret: conf.clientSecret,
- callbackURL: conf.callbackURL,
- scope: ['user:email']
- }, async (req, accessToken, refreshToken, profile, cb) => {
- try {
- const user = await WIKI.models.users.processProfile({
- providerKey: req.params.strategy,
- profile: {
- ...profile,
- picture: _.get(profile, 'photos[0].value', '')
- }
- })
- cb(null, user)
- } catch (err) {
- cb(err, null)
- }
- }
- ))
- }
-}
diff --git a/server/modules/authentication/firebase/definition.yml b/server/modules/authentication/firebase/definition.yml
deleted file mode 100644
index b8efe789..00000000
--- a/server/modules/authentication/firebase/definition.yml
+++ /dev/null
@@ -1,11 +0,0 @@
-key: firebase
-title: Firebase
-description: Firebase is Google's mobile platform that helps you quickly develop high-quality apps and grow your business.
-author: requarks.io
-logo: https://static.requarks.io/logo/firebase.svg
-color: yellow darken-3
-website: https://firebase.google.com/
-isAvailable: false
-useForm: false
-props: {}
-
diff --git a/server/modules/authentication/github/definition.yml b/server/modules/authentication/github/definition.yml
index 691e24e9..93022b5d 100644
--- a/server/modules/authentication/github/definition.yml
+++ b/server/modules/authentication/github/definition.yml
@@ -3,6 +3,7 @@ title: GitHub
description: GitHub Inc. is a web-based hosting service for version control using Git.
author: requarks.io
logo: https://static.requarks.io/logo/github.svg
+icon: /_assets/icons/ultraviolet-github.svg
color: grey darken-3
website: https://github.com
isAvailable: true
diff --git a/server/modules/authentication/gitlab/definition.yml b/server/modules/authentication/gitlab/definition.yml
index e18dccb8..ce3407c2 100644
--- a/server/modules/authentication/gitlab/definition.yml
+++ b/server/modules/authentication/gitlab/definition.yml
@@ -3,6 +3,7 @@ title: GitLab
description: GitLab is a web-based DevOps lifecycle tool that provides a Git-repository manager providing wiki, issue-tracking and CI/CD pipeline features.
author: requarks.io
logo: https://static.requarks.io/logo/gitlab.svg
+icon: /_assets/icons/ultraviolet-gitlab.svg
color: deep-orange
website: https://gitlab.com
isAvailable: true
diff --git a/server/modules/authentication/google/definition.yml b/server/modules/authentication/google/definition.yml
index 51747c37..435c6828 100644
--- a/server/modules/authentication/google/definition.yml
+++ b/server/modules/authentication/google/definition.yml
@@ -3,6 +3,7 @@ title: Google
description: Google specializes in Internet-related services and products, which include online advertising technologies, search engine, cloud computing, software, and hardware.
author: requarks.io
logo: https://static.requarks.io/logo/google.svg
+icon: /_assets/icons/ultraviolet-google.svg
color: red darken-1
website: https://console.developers.google.com/
isAvailable: true
diff --git a/server/modules/authentication/keycloak/definition.yml b/server/modules/authentication/keycloak/definition.yml
index df8ca666..59aaf38b 100644
--- a/server/modules/authentication/keycloak/definition.yml
+++ b/server/modules/authentication/keycloak/definition.yml
@@ -3,6 +3,7 @@ title: Keycloak
description: Keycloak is an open source software product to allow single sign-on with Identity Management and Access Management aimed at modern applications and services.
author: D4uS1
logo: https://static.requarks.io/logo/keycloak.svg
+icon: /_assets/icons/ultraviolet-keycloak.svg
color: blue-grey darken-2
website: https://www.keycloak.org/
useForm: false
diff --git a/server/modules/authentication/ldap/definition.yml b/server/modules/authentication/ldap/definition.yml
index 8b0b1b2d..af982089 100644
--- a/server/modules/authentication/ldap/definition.yml
+++ b/server/modules/authentication/ldap/definition.yml
@@ -3,7 +3,9 @@ title: LDAP / Active Directory
description: Active Directory is a directory service that Microsoft developed for the Windows domain networks.
author: requarks.io
logo: https://static.requarks.io/logo/active-directory.svg
+icon: /_assets/icons/ultraviolet-windows8.svg
color: blue darken-3
+vendor: Microsoft Corporation
website: https://www.microsoft.com/windowsserver
isAvailable: true
useForm: true
diff --git a/server/modules/authentication/local/definition.yml b/server/modules/authentication/local/definition.yml
index e4157ed6..7efaffd3 100644
--- a/server/modules/authentication/local/definition.yml
+++ b/server/modules/authentication/local/definition.yml
@@ -3,8 +3,10 @@ title: Local Database
description: Built-in authentication for Wiki.js
author: requarks.io
logo: https://static.requarks.io/logo/wikijs.svg
+icon: /_assets/icons/ultraviolet-data-protection.svg
color: primary
-website: https://wiki.js.org
+vendor: 'Wiki.js'
+website: 'https://js.wiki'
isAvailable: true
useForm: true
usernameType: email
diff --git a/server/modules/authentication/microsoft/definition.yml b/server/modules/authentication/microsoft/definition.yml
index 62cd3255..bf6f6b06 100644
--- a/server/modules/authentication/microsoft/definition.yml
+++ b/server/modules/authentication/microsoft/definition.yml
@@ -3,6 +3,7 @@ title: Microsoft
description: Microsoft is a software company, best known for it's Windows, Office, Azure, Xbox and Surface products.
author: requarks.io
logo: https://static.requarks.io/logo/microsoft.svg
+icon: /_assets/icons/ultraviolet-microsoft.svg
color: blue
website: https://apps.dev.microsoft.com/
isAvailable: false
diff --git a/server/modules/authentication/oauth2/definition.yml b/server/modules/authentication/oauth2/definition.yml
index 0621aa39..203b1a7c 100644
--- a/server/modules/authentication/oauth2/definition.yml
+++ b/server/modules/authentication/oauth2/definition.yml
@@ -3,6 +3,7 @@ title: Generic OAuth2
description: OAuth 2.0 is the industry-standard protocol for authorization.
author: requarks.io
logo: https://static.requarks.io/logo/oauth2.svg
+icon: /_assets/icons/ultraviolet-oauth2.svg
color: blue-grey darken-2
website: https://oauth.net/2/
isAvailable: true
diff --git a/server/modules/authentication/oidc/definition.yml b/server/modules/authentication/oidc/definition.yml
index 02812c4f..68a6ffc1 100644
--- a/server/modules/authentication/oidc/definition.yml
+++ b/server/modules/authentication/oidc/definition.yml
@@ -3,6 +3,7 @@ title: Generic OpenID Connect / OAuth2
description: OpenID Connect 1.0 is a simple identity layer on top of the OAuth 2.0 protocol.
author: requarks.io
logo: https://static.requarks.io/logo/oidc.svg
+icon: /_assets/icons/ultraviolet-openid.svg
color: blue-grey darken-2
website: http://openid.net/connect/
isAvailable: true
diff --git a/server/modules/authentication/okta/definition.yml b/server/modules/authentication/okta/definition.yml
index 734b5c92..74a16823 100644
--- a/server/modules/authentication/okta/definition.yml
+++ b/server/modules/authentication/okta/definition.yml
@@ -3,6 +3,7 @@ title: Okta
description: Okta provide secure identity management and single sign-on to any application.
author: requarks.io
logo: https://static.requarks.io/logo/okta.svg
+icon: /_assets/icons/ultraviolet-okta.svg
color: blue darken-1
website: https://www.okta.com/
isAvailable: true
diff --git a/server/modules/authentication/rocketchat/definition.yml b/server/modules/authentication/rocketchat/definition.yml
index a47af49c..e04a1724 100644
--- a/server/modules/authentication/rocketchat/definition.yml
+++ b/server/modules/authentication/rocketchat/definition.yml
@@ -3,6 +3,7 @@ title: Rocket.chat
description: Communicate and collaborate with your team, share files, chat in real-time, or switch to video/audio conferencing.
author: requarks.io
logo: https://static.requarks.io/logo/rocketchat.svg
+icon: /_assets/icons/ultraviolet-rocketchat.svg
color: red accent-3
website: https://rocket.chat/
isAvailable: true
diff --git a/server/modules/authentication/saml/definition.yml b/server/modules/authentication/saml/definition.yml
index bfb24d15..c3d0e7ff 100644
--- a/server/modules/authentication/saml/definition.yml
+++ b/server/modules/authentication/saml/definition.yml
@@ -3,6 +3,7 @@ title: SAML 2.0
description: Security Assertion Markup Language 2.0 (SAML 2.0) is a version of the SAML standard for exchanging authentication and authorization data between security domains.
author: requarks.io
logo: https://static.requarks.io/logo/saml.svg
+icon: /_assets/icons/ultraviolet-saml.svg
color: red darken-3
website: https://wiki.oasis-open.org/security/FrontPage
isAvailable: true
diff --git a/server/modules/authentication/slack/definition.yml b/server/modules/authentication/slack/definition.yml
index f5900b0f..6c57d951 100644
--- a/server/modules/authentication/slack/definition.yml
+++ b/server/modules/authentication/slack/definition.yml
@@ -3,6 +3,7 @@ title: Slack
description: Slack is a cloud-based set of proprietary team collaboration tools and services.
author: requarks.io
logo: https://static.requarks.io/logo/slack.svg
+icon: /_assets/icons/ultraviolet-slack.svg
color: green
website: https://api.slack.com/docs/oauth
isAvailable: true
diff --git a/server/modules/authentication/twitch/definition.yml b/server/modules/authentication/twitch/definition.yml
index aedda607..84f7587a 100644
--- a/server/modules/authentication/twitch/definition.yml
+++ b/server/modules/authentication/twitch/definition.yml
@@ -3,6 +3,7 @@ title: Twitch
description: Twitch is a live streaming video platform.
author: requarks.io
logo: https://static.requarks.io/logo/twitch.svg
+icon: /_assets/icons/ultraviolet-twitch.svg
color: indigo darken-2
website: https://dev.twitch.tv/docs/authentication/
isAvailable: true
diff --git a/ux/public/_assets/icons/ultraviolet-auth0.svg b/ux/public/_assets/icons/ultraviolet-auth0.svg
new file mode 100644
index 00000000..801cbd26
--- /dev/null
+++ b/ux/public/_assets/icons/ultraviolet-auth0.svg
@@ -0,0 +1,10 @@
+
+
diff --git a/ux/public/_assets/icons/ultraviolet-gitlab.svg b/ux/public/_assets/icons/ultraviolet-gitlab.svg
new file mode 100644
index 00000000..c0fdee5c
--- /dev/null
+++ b/ux/public/_assets/icons/ultraviolet-gitlab.svg
@@ -0,0 +1,14 @@
+
+
+
diff --git a/ux/public/_assets/icons/ultraviolet-keycloak.svg b/ux/public/_assets/icons/ultraviolet-keycloak.svg
new file mode 100644
index 00000000..eaa496c8
--- /dev/null
+++ b/ux/public/_assets/icons/ultraviolet-keycloak.svg
@@ -0,0 +1,13 @@
+
+
+
diff --git a/ux/public/_assets/icons/ultraviolet-oauth2.svg b/ux/public/_assets/icons/ultraviolet-oauth2.svg
new file mode 100644
index 00000000..a85fa2f3
--- /dev/null
+++ b/ux/public/_assets/icons/ultraviolet-oauth2.svg
@@ -0,0 +1,12 @@
+
+
diff --git a/ux/public/_assets/icons/ultraviolet-okta.svg b/ux/public/_assets/icons/ultraviolet-okta.svg
new file mode 100644
index 00000000..868851d7
--- /dev/null
+++ b/ux/public/_assets/icons/ultraviolet-okta.svg
@@ -0,0 +1,7 @@
+
+
+
diff --git a/ux/public/_assets/icons/ultraviolet-openid.svg b/ux/public/_assets/icons/ultraviolet-openid.svg
new file mode 100644
index 00000000..82bf0459
--- /dev/null
+++ b/ux/public/_assets/icons/ultraviolet-openid.svg
@@ -0,0 +1,11 @@
+
+
+
diff --git a/ux/public/_assets/icons/ultraviolet-rename.svg b/ux/public/_assets/icons/ultraviolet-rename.svg
new file mode 100644
index 00000000..d9e4bcb7
--- /dev/null
+++ b/ux/public/_assets/icons/ultraviolet-rename.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/ux/public/_assets/icons/ultraviolet-rocketchat.svg b/ux/public/_assets/icons/ultraviolet-rocketchat.svg
new file mode 100644
index 00000000..2381cf64
--- /dev/null
+++ b/ux/public/_assets/icons/ultraviolet-rocketchat.svg
@@ -0,0 +1,13 @@
+
+
+
diff --git a/ux/public/_assets/icons/ultraviolet-saml.svg b/ux/public/_assets/icons/ultraviolet-saml.svg
new file mode 100644
index 00000000..69c8c806
--- /dev/null
+++ b/ux/public/_assets/icons/ultraviolet-saml.svg
@@ -0,0 +1,7 @@
+
+
+
diff --git a/ux/public/_assets/icons/ultraviolet-twitch.svg b/ux/public/_assets/icons/ultraviolet-twitch.svg
index 263ee07b..689aa92a 100644
--- a/ux/public/_assets/icons/ultraviolet-twitch.svg
+++ b/ux/public/_assets/icons/ultraviolet-twitch.svg
@@ -1 +1,9 @@
-
\ No newline at end of file
+
+
diff --git a/ux/src/i18n/locales/en.json b/ux/src/i18n/locales/en.json
index 9689bf8a..652dd886 100644
--- a/ux/src/i18n/locales/en.json
+++ b/ux/src/i18n/locales/en.json
@@ -1443,5 +1443,11 @@
"admin.utilities.exportHint": "Export content to tarball for backup / migration.",
"admin.utilities.importHint": "Import content from a tarball backup or a 2.X backup.",
"admin.utilities.flushCache": "Flush Cache",
- "admin.utilities.flushCacheHint": "Pages and Assets are cached to disk for better performance. You can flush the cache to force all content to be fetched from the DB again."
+ "admin.utilities.flushCacheHint": "Pages and Assets are cached to disk for better performance. You can flush the cache to force all content to be fetched from the DB again.",
+ "admin.auth.enabledForced": "This strategy cannot be disabled.",
+ "admin.auth.enabled": "Enabled",
+ "admin.auth.enabledHint": "Should this strategy be available to sites for login.",
+ "admin.auth.vendor": "Vendor",
+ "admin.auth.vendorWebsite": "Website",
+ "admin.auth.status": "Status"
}
diff --git a/ux/src/pages/AdminAuth.vue b/ux/src/pages/AdminAuth.vue
index a309754d..9064bd5d 100644
--- a/ux/src/pages/AdminAuth.vue
+++ b/ux/src/pages/AdminAuth.vue
@@ -33,11 +33,11 @@ q-page.admin-mail
dark
)
q-item(
- v-for='str of state.activeStrategies'
+ v-for='str of combinedActiveStrategies'
:key='str.key'
active-class='bg-primary text-white'
- :active='state.selectedStrategy === str.key'
- @click='state.selectedStrategy = str.key'
+ :active='state.selectedStrategy === str.id'
+ @click='state.selectedStrategy = str.id'
clickable
)
q-item-section(side)
@@ -54,54 +54,159 @@ q-page.admin-mail
icon='las la-plus'
:label='t(`admin.auth.addStrategy`)'
)
- q-menu(auto-close)
- q-list(style='min-width: 350px;')
- q-item(clickable)
- .col Doude
+ q-menu(auto-close, fit, max-width='300px')
+ q-list(separator)
+ q-item(
+ v-for='str of availableStrategies'
+ :key='str.key'
+ clickable
+ @click='addStrategy(str)'
+ )
+ q-item-section(avatar)
+ q-avatar(
+ rounded
+ color='dark'
+ text-color='white'
+ )
+ q-icon(
+ :name='`img:` + str.icon'
+ )
+ q-item-section
+ q-item-label: strong {{str.title}}
+ q-item-label(caption, lines='2') {{str.description}}
+ .col
+ q-card.shadow-1.q-pb-sm
+ q-card-section
+ .text-subtitle1 {{t('admin.storage.contentTypes')}}
+ .text-body2.text-grey {{ t('admin.storage.contentTypesHint') }}
- //- v-flex(lg3, xs12)
- //- v-card.animated.fadeInUp
- //- v-toolbar(flat, color='teal', dark, dense)
- //- .subtitle-1 {{$t('admin.auth.activeStrategies')}}
- //- v-list(two-line, dense).py-0
- //- draggable(
- //- v-model='activeStrategies'
- //- handle='.is-handle'
- //- direction='vertical'
- //- )
- //- transition-group
- //- v-list-item(
- //- v-for='(str, idx) in activeStrategies'
- //- :key='str.key'
- //- @click='selectedStrategy = str.key'
- //- :class='selectedStrategy === str.key ? ($vuetify.theme.dark ? `grey darken-5` : `teal lighten-5`) : ``'
- //- )
- //- v-list-item-avatar.is-handle(size='24')
- //- v-icon(:color='selectedStrategy === str.key ? `teal` : `grey`') mdi-drag-horizontal
- //- v-list-item-content
- //- v-list-item-title.body-2(:class='selectedStrategy === str.key ? `teal--text` : ``') {{ str.displayName }}
- //- v-list-item-subtitle: .caption(:class='selectedStrategy === str.key ? `teal--text ` : ``') {{ str.strategy.title }}
- //- v-list-item-avatar(v-if='selectedStrategy === str.key', size='24')
- //- v-icon.animated.fadeInLeft(color='teal', large) mdi-chevron-right
- //- v-card-chin
- //- v-menu(offset-y, bottom, min-width='250px', max-width='550px', max-height='50vh', style='flex: 1 1;', center)
- //- template(v-slot:activator='{ on }')
- //- v-btn(v-on='on', color='primary', depressed, block)
- //- v-icon(left) mdi-plus
- //- span {{$t('admin.auth.addStrategy')}}
- //- v-list(dense)
- //- template(v-for='(str, idx) of strategies')
- //- v-list-item(
- //- :key='str.key'
- //- :disabled='str.isDisabled'
- //- @click='addStrategy(str)'
- //- )
- //- v-list-item-avatar(height='24', width='48', tile)
- //- v-img(:src='str.logo', width='48px', height='24px', contain, :style='str.isDisabled ? `opacity: .25;` : ``')
- //- v-list-item-content
- //- v-list-item-title {{str.title}}
- //- v-list-item-subtitle: .caption(:style='str.isDisabled ? `opacity: .4;` : ``') {{str.description}}
- //- v-divider(v-if='idx < strategies.length - 1')
+ //- -----------------------
+ //- Configuration
+ //- -----------------------
+ q-card.shadow-1.q-pb-sm.q-mt-md
+ q-card-section
+ .text-subtitle1 {{t('admin.storage.config')}}
+ q-banner.q-mt-md(
+ v-if='!state.strategy.config || Object.keys(state.strategy.config).length < 1'
+ rounded
+ :class='$q.dark.isActive ? `bg-negative text-white` : `bg-grey-2 text-grey-7`'
+ ) {{t('admin.storage.noConfigOption')}}
+ template(
+ v-for='(cfg, cfgKey, idx) in state.strategy.config'
+ )
+ template(
+ v-if='configIfCheck(cfg.if)'
+ )
+ q-separator.q-my-sm(inset, v-if='idx > 0')
+ q-item(v-if='cfg.type === `boolean`', tag='label')
+ blueprint-icon(:icon='cfg.icon', :hue-rotate='cfg.readOnly ? -45 : 0')
+ q-item-section
+ q-item-label {{cfg.title}}
+ q-item-label(caption) {{cfg.hint}}
+ q-item-section(avatar)
+ q-toggle(
+ v-model='cfg.value'
+ color='primary'
+ checked-icon='las la-check'
+ unchecked-icon='las la-times'
+ :aria-label='t(`admin.general.allowComments`)'
+ :disable='cfg.readOnly'
+ )
+ q-item(v-else)
+ blueprint-icon(:icon='cfg.icon', :hue-rotate='cfg.readOnly ? -45 : 0')
+ q-item-section
+ q-item-label {{cfg.title}}
+ q-item-label(caption) {{cfg.hint}}
+ q-item-section(
+ :style='cfg.type === `number` ? `flex: 0 0 150px;` : ``'
+ :class='{ "col-auto": cfg.enum && cfg.enumDisplay === `buttons` }'
+ )
+ q-btn-toggle(
+ v-if='cfg.enum && cfg.enumDisplay === `buttons`'
+ v-model='cfg.value'
+ push
+ glossy
+ no-caps
+ toggle-color='primary'
+ :options='cfg.enum'
+ :disable='cfg.readOnly'
+ )
+ q-select(
+ v-else-if='cfg.enum'
+ outlined
+ v-model='cfg.value'
+ :options='cfg.enum'
+ emit-value
+ map-options
+ dense
+ options-dense
+ :aria-label='cfg.title'
+ :disable='cfg.readOnly'
+ )
+ q-input(
+ v-else
+ outlined
+ v-model='cfg.value'
+ dense
+ :type='cfg.multiline ? `textarea` : `input`'
+ :aria-label='cfg.title'
+ :disable='cfg.readOnly'
+ )
+
+ .col-auto(v-if='state.selectedStrategy && state.strategy')
+ //- -----------------------
+ //- Infobox
+ //- -----------------------
+ q-card.rounded-borders.q-pb-md(style='width: 350px;')
+ q-card-section
+ .text-subtitle1 {{state.strategy.strategy.title}}
+ q-img.q-mt-sm.rounded-borders(
+ :src='state.strategy.strategy.logo'
+ fit='cover'
+ no-spinner
+ )
+ .text-body2.q-mt-md {{state.strategy.strategy.description}}
+ q-separator.q-mb-sm(inset)
+ q-item
+ q-item-section
+ q-item-label.text-grey {{t(`admin.auth.vendor`)}}
+ q-item-label {{state.strategy.strategy.vendor}}
+ q-separator.q-my-sm(inset)
+ q-item
+ q-item-section
+ q-item-label.text-grey {{t(`admin.auth.vendorWebsite`)}}
+ q-item-label: a(:href='state.strategy.strategy.website', target='_blank', rel='noreferrer') {{state.strategy.strategy.website}}
+
+ //- -----------------------
+ //- Status
+ //- -----------------------
+ q-card.rounded-borders.q-pb-md.q-mt-md(style='width: 350px;')
+ q-card-section
+ .text-subtitle1 {{t(`admin.auth.status`)}}
+ q-item(tag='label')
+ q-item-section
+ q-item-label {{t(`admin.auth.enabled`)}}
+ q-item-label(caption) {{t(`admin.auth.enabledHint`)}}
+ q-item-label.text-deep-orange(v-if='state.strategy.strategy.key === `local`', caption) {{t(`admin.auth.enabledForced`)}}
+ q-item-section(avatar)
+ q-toggle(
+ v-model='state.strategy.isEnabled'
+ :disable='state.strategy.strategy.key === `local`'
+ color='primary'
+ checked-icon='las la-check'
+ unchecked-icon='las la-times'
+ :aria-label='t(`admin.auth.enabled`)'
+ )
+ q-separator.q-my-sm(inset)
+ q-item
+ q-item-section
+ q-btn.acrylic-btn(
+ icon='las la-trash-alt'
+ flat
+ color='negative'
+ :disable='state.strategy.strategy.key === `local`'
+ label='Delete Strategy'
+ )
//- v-flex(xs12, lg9)
//- v-card.animated.fadeInUp.wait-p2s
@@ -263,7 +368,7 @@ q-page.admin-mail
diff --git a/ux/src/pages/AdminStorage.vue b/ux/src/pages/AdminStorage.vue
index 81d7b8ae..74ce923a 100644
--- a/ux/src/pages/AdminStorage.vue
+++ b/ux/src/pages/AdminStorage.vue
@@ -438,7 +438,7 @@ q-page.admin-storage
//- -----------------------
q-card.rounded-borders.q-pb-md.q-mt-md(style='width: 350px;')
q-card-section
- .text-subtitle1 Status
+ .text-subtitle1 {{ t('admin.storage.status') }}
template(v-if='state.target.module !== `db` && !(state.target.setup && state.target.setup.handler && state.target.setup.state !== `configured`)')
q-item(tag='label')
q-item-section
@@ -452,7 +452,7 @@ q-page.admin-storage
color='primary'
checked-icon='las la-check'
unchecked-icon='las la-times'
- :aria-label='t(`admin.general.allowSearch`)'
+ :aria-label='t(`admin.storage.enabled`)'
)
q-separator.q-my-sm(inset)
q-item