Merge branch 'ldap-auth-update' into 'dev'
Update LDAP to use Alternate Login System See merge request Shinobi-Systems/Shinobi!298auto-build-api-doc-with-code
commit
56d15a179a
|
|
@ -4224,6 +4224,11 @@ module.exports = function(s,config,lang){
|
||||||
"fieldType": 'div',
|
"fieldType": 'div',
|
||||||
"id": "alternate-logins"
|
"id": "alternate-logins"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"fieldType": "btn-group",
|
||||||
|
"forForm": true,
|
||||||
|
"btns": [],
|
||||||
|
},
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"2-Factor Authentication": {
|
"2-Factor Authentication": {
|
||||||
|
|
@ -4550,75 +4555,6 @@ module.exports = function(s,config,lang){
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"LDAP": {
|
|
||||||
"evaluation":"details.use_ldap!=='0'",
|
|
||||||
"name": lang["LDAP"],
|
|
||||||
"color": "forestgreen",
|
|
||||||
"info": [
|
|
||||||
{
|
|
||||||
"name": "detail=ldap_enable",
|
|
||||||
"selector":"ldap_i",
|
|
||||||
"field": lang.Enabled,
|
|
||||||
"description": "Enable LDAP authentication for this Group.",
|
|
||||||
"default": "0",
|
|
||||||
"example": "",
|
|
||||||
"fieldType": "select",
|
|
||||||
"possible": [
|
|
||||||
{
|
|
||||||
"name": lang.No,
|
|
||||||
"value": "0"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": lang.Yes,
|
|
||||||
"value": "1"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"form-group-class": "ldap_i_input ldap_i_1",
|
|
||||||
"name": "detail=ldap_url",
|
|
||||||
"field": lang.URL,
|
|
||||||
"description": "",
|
|
||||||
"example": "",
|
|
||||||
"possible": ""
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"placeholder":lang.Example + " : cn=admin,dc=test,dc=com",
|
|
||||||
"form-group-class": "ldap_i_input ldap_i_1",
|
|
||||||
"name": "detail=ldap_bindDN",
|
|
||||||
"field": lang.bindDN,
|
|
||||||
"description": "",
|
|
||||||
"example": "",
|
|
||||||
"possible": ""
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"form-group-class": "ldap_i_input ldap_i_1",
|
|
||||||
"name": "detail=ldap_bindCredentials",
|
|
||||||
"field": lang['Bind Credentials'],
|
|
||||||
"description": "",
|
|
||||||
"example": "",
|
|
||||||
"possible": ""
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"placeholder": "cn={{username}}",
|
|
||||||
"form-group-class": "ldap_i_input ldap_i_1",
|
|
||||||
"name": "detail=ldap_searchFilter",
|
|
||||||
"field": lang['Search Filter'],
|
|
||||||
"description": "",
|
|
||||||
"example": "",
|
|
||||||
"possible": ""
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"placeholder": "dc=test,dc=com",
|
|
||||||
"form-group-class": "ldap_i_input ldap_i_1",
|
|
||||||
"name": "detail=ldap_searchBase",
|
|
||||||
"field": lang['Search Base'],
|
|
||||||
"description": "",
|
|
||||||
"example": "",
|
|
||||||
"possible": ""
|
|
||||||
},
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"Preferences": {
|
"Preferences": {
|
||||||
"name": lang.Preferences,
|
"name": lang.Preferences,
|
||||||
"color": "navy",
|
"color": "navy",
|
||||||
|
|
@ -5454,6 +5390,67 @@ module.exports = function(s,config,lang){
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"LDAP": {
|
||||||
|
"section": "LDAP",
|
||||||
|
"blocks": {
|
||||||
|
"LDAP": {
|
||||||
|
"evaluation":"details.use_ldap!=='0'",
|
||||||
|
"name": lang["LDAP"],
|
||||||
|
"color": "forestgreen",
|
||||||
|
"info": [
|
||||||
|
{
|
||||||
|
"name": "ldap_url",
|
||||||
|
"field": lang.URL,
|
||||||
|
"description": "",
|
||||||
|
"example": "ldap://127.0.0.1:389",
|
||||||
|
"possible": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "username",
|
||||||
|
"field": lang.Username,
|
||||||
|
"description": "",
|
||||||
|
"example": "",
|
||||||
|
"possible": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "password",
|
||||||
|
"field": lang.Password,
|
||||||
|
"description": "",
|
||||||
|
"example": "",
|
||||||
|
"possible": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ldap_bindDN",
|
||||||
|
"field": lang.bindDN,
|
||||||
|
"description": "",
|
||||||
|
"example": "cn=admin,dc=test,dc=com",
|
||||||
|
"possible": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ldap_searchBase",
|
||||||
|
"field": lang['Search Base'],
|
||||||
|
"description": "",
|
||||||
|
"example": "dc=test,dc=com",
|
||||||
|
"possible": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ldap_searchFilter",
|
||||||
|
"field": lang['Search Filter'],
|
||||||
|
"description": "",
|
||||||
|
"example": "uid={{username}}",
|
||||||
|
"possible": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldType": "btn",
|
||||||
|
"forForm": true,
|
||||||
|
"attribute": `type="submit"`,
|
||||||
|
"class": `btn-success`,
|
||||||
|
"btnContent": `<i class="fa fa-check"></i> ${lang['Save']}`,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -121,6 +121,7 @@
|
||||||
"Home": "Home",
|
"Home": "Home",
|
||||||
"alreadyLinked": "Already Linked to an Account",
|
"alreadyLinked": "Already Linked to an Account",
|
||||||
"Link Google Account": "Link Google Account",
|
"Link Google Account": "Link Google Account",
|
||||||
|
"Link LDAP Account": "Link LDAP Account",
|
||||||
"noLoginTokensAdded": "There are no Alternate Logins associated to this account.",
|
"noLoginTokensAdded": "There are no Alternate Logins associated to this account.",
|
||||||
"tokenNotUserBound": "This Login Handle is not linked to a user on this server!",
|
"tokenNotUserBound": "This Login Handle is not linked to a user on this server!",
|
||||||
"tokenNotUserBoundPt2": "Type your credentials then use the Google Sign-In button to link quickly.",
|
"tokenNotUserBoundPt2": "Type your credentials then use the Google Sign-In button to link quickly.",
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ module.exports = (s,config,lang,app) => {
|
||||||
bindLoginIdToUser,
|
bindLoginIdToUser,
|
||||||
refreshLoginTokenAccessDate,
|
refreshLoginTokenAccessDate,
|
||||||
} = require('./alternateLogins.js')(s,config,lang)
|
} = require('./alternateLogins.js')(s,config,lang)
|
||||||
console.error(`Google App ID : ${config.appIdGoogleSignIn}`)
|
console.log(`Google App ID : ${config.appIdGoogleSignIn}`)
|
||||||
const client = new OAuth2Client(config.appIdGoogleSignIn);
|
const client = new OAuth2Client(config.appIdGoogleSignIn);
|
||||||
async function verifyToken(userLoginToken) {
|
async function verifyToken(userLoginToken) {
|
||||||
const ticket = await client.verifyIdToken({
|
const ticket = await client.verifyIdToken({
|
||||||
|
|
@ -61,7 +61,7 @@ module.exports = (s,config,lang,app) => {
|
||||||
return response
|
return response
|
||||||
}
|
}
|
||||||
s.onProcessReady(() => {
|
s.onProcessReady(() => {
|
||||||
config.renderPaths.loginTokenAddGoogle = `pages/loginTokenAddGoogle`
|
config.renderPaths.loginTokenAddGoogle = `pages/blocks/loginTokenAddGoogle`
|
||||||
s.alternateLogins['google'] = async (params) => {
|
s.alternateLogins['google'] = async (params) => {
|
||||||
const response = { ok: false }
|
const response = { ok: false }
|
||||||
const loginToken = params.alternateLoginToken
|
const loginToken = params.alternateLoginToken
|
||||||
|
|
@ -95,9 +95,8 @@ module.exports = (s,config,lang,app) => {
|
||||||
}
|
}
|
||||||
return response
|
return response
|
||||||
}
|
}
|
||||||
s.definitions["Account Settings"].blocks["AlternateLogins"].info.push({
|
const alternateLoginsFieldList = s.definitions["Account Settings"].blocks["AlternateLogins"].info
|
||||||
"form-group-class-pre-layer": "form-group",
|
alternateLoginsFieldList[alternateLoginsFieldList.length - 1].btns.push({
|
||||||
"fieldType": "btn",
|
|
||||||
"class": `btn-info google-sign-in`,
|
"class": `btn-info google-sign-in`,
|
||||||
"btnContent": `<i class="fa fa-google"></i> ${lang['Link Google Account']}`,
|
"btnContent": `<i class="fa fa-google"></i> ${lang['Link Google Account']}`,
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,217 @@
|
||||||
|
const LdapAuth = require('ldapauth-fork');
|
||||||
|
module.exports = (s,config,lang,app) => {
|
||||||
|
const {
|
||||||
|
basicAuth,
|
||||||
|
} = require('./utils.js')(s,config,lang)
|
||||||
|
const {
|
||||||
|
getLoginToken,
|
||||||
|
deleteLoginToken,
|
||||||
|
bindLoginIdToUser,
|
||||||
|
refreshLoginTokenAccessDate,
|
||||||
|
} = require('./alternateLogins.js')(s,config,lang)
|
||||||
|
async function ldapAuth(params) {
|
||||||
|
return new Promise((resolve,reject) => {
|
||||||
|
const response = { ok: false }
|
||||||
|
let ldapUrl = params.url
|
||||||
|
ldapUrl = ldapUrl.startsWith('ldap://') ? ldapUrl : `ldap://${ldapUrl}`
|
||||||
|
const host = ldapUrl.split('://')[1]
|
||||||
|
const username = params.username// || 'ubuntu2'
|
||||||
|
const password = params.password// || 'moeiscool'
|
||||||
|
const bindDN = params.bindDN// || 'uid=ubuntu2,ou=People,dc=example,dc=com'
|
||||||
|
const searchBase = params.searchBase// || 'ou=People,dc=example,dc=com'
|
||||||
|
let searchFilter = params.searchFilter// || '(uid={{username}})'
|
||||||
|
searchFilter = searchFilter.startsWith('(') ? searchFilter : '(' + searchFilter
|
||||||
|
searchFilter = searchFilter.endsWith(')') ? searchFilter : searchFilter + ')'
|
||||||
|
const ldap = new LdapAuth({
|
||||||
|
url: ldapUrl,
|
||||||
|
bindDN: bindDN,
|
||||||
|
bindCredentials: password,
|
||||||
|
searchBase: searchBase,
|
||||||
|
searchFilter: searchFilter,
|
||||||
|
reconnect: true
|
||||||
|
})
|
||||||
|
|
||||||
|
ldap.authenticate(username, password, function(err, user) {
|
||||||
|
if(err){
|
||||||
|
response.err = err
|
||||||
|
}else{
|
||||||
|
response.ok = true
|
||||||
|
response.user = {
|
||||||
|
id: host + '_' + user.uidNumber,
|
||||||
|
name: user.givenName + ' ' + user.sn,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
resolve(response)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
async function loginWithLdapAccount(params) {
|
||||||
|
const response = {ok: false, ldapSignedIn: false}
|
||||||
|
const tokenResponse = await ldapAuth(params)
|
||||||
|
if(tokenResponse.ok){
|
||||||
|
const user = tokenResponse.user
|
||||||
|
response.ldapSignedIn = true
|
||||||
|
response.ldapUser = user
|
||||||
|
const foundToken = await getLoginToken(user.id,'ldap')
|
||||||
|
if(foundToken){
|
||||||
|
const userResponse = await s.knexQueryPromise({
|
||||||
|
action: "select",
|
||||||
|
columns: '*',
|
||||||
|
table: "Users",
|
||||||
|
where: [
|
||||||
|
['uid','=',foundToken.uid],
|
||||||
|
['ke','=',foundToken.ke],
|
||||||
|
],
|
||||||
|
limit: 1
|
||||||
|
})
|
||||||
|
response.ok = true
|
||||||
|
userResponse.rows[0].details = s.parseJSON(userResponse.rows[0].details)
|
||||||
|
response.user = userResponse.rows[0]
|
||||||
|
}else{
|
||||||
|
response.msg = lang.tokenNotUserBound
|
||||||
|
// make new if no users?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return response
|
||||||
|
}
|
||||||
|
async function updateLdapBaseDetails(params,updateFields){
|
||||||
|
const url = updateFields.ldap_url
|
||||||
|
const bindDN = updateFields.ldap_bindDN
|
||||||
|
const searchBase = updateFields.ldap_searchBase
|
||||||
|
const searchFilter = updateFields.ldap_searchFilter
|
||||||
|
const userResponse = await s.knexQueryPromise({
|
||||||
|
action: "select",
|
||||||
|
columns: "*",
|
||||||
|
table: "Users",
|
||||||
|
where: [
|
||||||
|
['ke','=',params.groupKey],
|
||||||
|
['uid','=',params.userId],
|
||||||
|
],
|
||||||
|
})
|
||||||
|
const userDetails = JSON.parse(userResponse.rows[0].details)
|
||||||
|
userDetails.ldap_url = url
|
||||||
|
userDetails.ldap_bindDN = bindDN
|
||||||
|
userDetails.ldap_searchBase = searchBase
|
||||||
|
userDetails.ldap_searchFilter = searchFilter
|
||||||
|
await s.knexQueryPromise({
|
||||||
|
action: "update",
|
||||||
|
table: "Users",
|
||||||
|
update: {
|
||||||
|
details: JSON.stringify(userDetails)
|
||||||
|
},
|
||||||
|
where: [
|
||||||
|
['ke','=',params.groupKey],
|
||||||
|
['uid','=',params.userId],
|
||||||
|
]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
s.onProcessReady(() => {
|
||||||
|
config.renderPaths.loginTokenAddLDAP = `pages/blocks/loginTokenAddLDAP`
|
||||||
|
s.alternateLogins['ldap'] = async (params) => {
|
||||||
|
const response = { ok: false }
|
||||||
|
const groupKey = params.key
|
||||||
|
const userResponse = await s.knexQueryPromise({
|
||||||
|
action: "select",
|
||||||
|
columns: "*",
|
||||||
|
table: "Users",
|
||||||
|
where: [
|
||||||
|
['ke','=',params.key],
|
||||||
|
['details','NOT LIKE','%"sub"%'],
|
||||||
|
],
|
||||||
|
})
|
||||||
|
if(userResponse.rows[0]){
|
||||||
|
const userDetails = JSON.parse(userResponse.rows[0].details)
|
||||||
|
const url = userDetails.ldap_url
|
||||||
|
const bindDN = userDetails.ldap_bindDN
|
||||||
|
const searchBase = userDetails.ldap_searchBase
|
||||||
|
const searchFilter = userDetails.ldap_searchFilter
|
||||||
|
const username = params.mail
|
||||||
|
const password = params.pass
|
||||||
|
const ldapLoginResponse = await loginWithLdapAccount({
|
||||||
|
url: url,
|
||||||
|
username: username,
|
||||||
|
password: password,
|
||||||
|
bindDN: bindDN,
|
||||||
|
searchBase: searchBase,
|
||||||
|
searchFilter: searchFilter,
|
||||||
|
})
|
||||||
|
if(ldapLoginResponse.user){
|
||||||
|
const user = ldapLoginResponse.user
|
||||||
|
response.ok = true
|
||||||
|
response.user = user
|
||||||
|
refreshLoginTokenAccessDate(ldapLoginResponse.ldapUser.id,'ldap')
|
||||||
|
}else{
|
||||||
|
response.msg = ldapLoginResponse.msg
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return response
|
||||||
|
}
|
||||||
|
const alternateLoginsFieldList = s.definitions["Account Settings"].blocks["AlternateLogins"].info
|
||||||
|
alternateLoginsFieldList[alternateLoginsFieldList.length - 1].btns.push({
|
||||||
|
"class": `btn-info ldap-sign-in`,
|
||||||
|
"btnContent": `<i class="fa fa-group"></i> ${lang['Link LDAP Account']}`,
|
||||||
|
})
|
||||||
|
s.customAutoLoadTree['LibsJs'].push(`dash2.ldapSignIn.js`)
|
||||||
|
})
|
||||||
|
/**
|
||||||
|
* API : Add Token Window (Sign-In to LDAP) (GET)
|
||||||
|
*/
|
||||||
|
app.get(config.webPaths.apiPrefix+':auth/loginTokenAddLDAP/:ke', function (req,res){
|
||||||
|
s.auth(req.params,(user) => {
|
||||||
|
s.renderPage(req,res,config.renderPaths.loginTokenAddLDAP,{
|
||||||
|
lang: lang,
|
||||||
|
define: s.getDefinitonFile(user.details.lang),
|
||||||
|
config: s.getConfigWithBranding(req.hostname),
|
||||||
|
$user: user
|
||||||
|
})
|
||||||
|
},res,req);
|
||||||
|
});
|
||||||
|
/**
|
||||||
|
* API : Add Token Window (Sign-In to LDAP) (POST)
|
||||||
|
*/
|
||||||
|
app.post(config.webPaths.apiPrefix+':auth/loginTokenAddLDAP/:ke', function (req,res){
|
||||||
|
const response = {ok: false};
|
||||||
|
s.auth(req.params,async (user) => {
|
||||||
|
const userId = user.uid
|
||||||
|
const groupKey = req.params.ke
|
||||||
|
const url = req.body.ldap_url
|
||||||
|
const bindDN = req.body.ldap_bindDN
|
||||||
|
const searchBase = req.body.ldap_searchBase
|
||||||
|
const searchFilter = req.body.ldap_searchFilter
|
||||||
|
const username = req.body.username
|
||||||
|
const password = req.body.password
|
||||||
|
const authPostBody = {
|
||||||
|
url: url,
|
||||||
|
username: username,
|
||||||
|
password: password,
|
||||||
|
bindDN: bindDN,
|
||||||
|
searchBase: searchBase,
|
||||||
|
searchFilter: searchFilter,
|
||||||
|
}
|
||||||
|
const tokenResponse = await ldapAuth(authPostBody)
|
||||||
|
if(tokenResponse.ok){
|
||||||
|
const ldapUser = tokenResponse.user
|
||||||
|
const loginId = ldapUser.id
|
||||||
|
if(!user.details.sub){
|
||||||
|
updateLdapBaseDetails({
|
||||||
|
groupKey: groupKey,
|
||||||
|
userId: user.uid,
|
||||||
|
},req.body)
|
||||||
|
}
|
||||||
|
const bindResponse = await bindLoginIdToUser({
|
||||||
|
loginId: loginId,
|
||||||
|
ke: groupKey,
|
||||||
|
uid: userId,
|
||||||
|
name: ldapUser.name,
|
||||||
|
type: 'ldap'
|
||||||
|
})
|
||||||
|
response.ok = bindResponse.ok
|
||||||
|
response.msg = bindResponse.msg
|
||||||
|
}
|
||||||
|
s.closeJsonResponse(res,response)
|
||||||
|
},res,req);
|
||||||
|
});
|
||||||
|
return {
|
||||||
|
loginWithLdapAccount: loginWithLdapAccount,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -5,4 +5,8 @@ module.exports = (s,config,lang,app) => {
|
||||||
s.debugLog('Google')
|
s.debugLog('Google')
|
||||||
require('./google.js')(s,config,lang,app)
|
require('./google.js')(s,config,lang,app)
|
||||||
}
|
}
|
||||||
|
if(config.allowLdapSignOn){
|
||||||
|
s.debugLog('LDAP')
|
||||||
|
require('./ldap.js')(s,config,lang,app)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,8 @@ module.exports = function(s,config,lang){
|
||||||
userDetails.bb_b2_applicationKey &&
|
userDetails.bb_b2_applicationKey &&
|
||||||
userDetails.bb_b2_applicationKey !=='' &&
|
userDetails.bb_b2_applicationKey !=='' &&
|
||||||
userDetails.bb_b2_bucket &&
|
userDetails.bb_b2_bucket &&
|
||||||
userDetails.bb_b2_bucket !== ''
|
userDetails.bb_b2_bucket !== '' &&
|
||||||
|
userDetails.bb_b2_save === '1'
|
||||||
){
|
){
|
||||||
var B2 = require('backblaze-b2')
|
var B2 = require('backblaze-b2')
|
||||||
if(!userDetails.bb_b2_dir || userDetails.bb_b2_dir === '/'){
|
if(!userDetails.bb_b2_dir || userDetails.bb_b2_dir === '/'){
|
||||||
|
|
|
||||||
|
|
@ -26,9 +26,6 @@ module.exports = function(s,config,lang,app,io){
|
||||||
twoFactorVerification,
|
twoFactorVerification,
|
||||||
ldapLogin,
|
ldapLogin,
|
||||||
} = require('./auth/utils.js')(s,config,lang)
|
} = require('./auth/utils.js')(s,config,lang)
|
||||||
if(config.productType === 'Pro'){
|
|
||||||
var LdapAuth = require('ldapauth-fork');
|
|
||||||
}
|
|
||||||
s.renderPage = function(req,res,paths,passables,callback){
|
s.renderPage = function(req,res,paths,passables,callback){
|
||||||
passables.window = {}
|
passables.window = {}
|
||||||
passables.data = req.params
|
passables.data = req.params
|
||||||
|
|
@ -447,138 +444,7 @@ module.exports = function(s,config,lang,app,io){
|
||||||
failedAuthentication(req.body.function,req.body.mail)
|
failedAuthentication(req.body.function,req.body.mail)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(LdapAuth&&req.body.function==='ldap'&&req.body.key!==''){
|
if(req.body.function === 'super'){
|
||||||
s.knexQuery({
|
|
||||||
action: "select",
|
|
||||||
columns: "*",
|
|
||||||
table: "Users",
|
|
||||||
where: [
|
|
||||||
['ke','=',req.body.key],
|
|
||||||
['details','NOT LIKE','%"sub"%'],
|
|
||||||
],
|
|
||||||
},(err,r) => {
|
|
||||||
if(r&&r[0]){
|
|
||||||
r=r[0]
|
|
||||||
r.details=JSON.parse(r.details)
|
|
||||||
r.lang=s.getLanguageFile(r.details.lang)
|
|
||||||
if(r.details.use_ldap!=='0'&&r.details.ldap_enable==='1'&&r.details.ldap_url&&r.details.ldap_url!==''){
|
|
||||||
req.mailArray={}
|
|
||||||
req.body.mail.split(',').forEach(function(v){
|
|
||||||
v=v.split('=')
|
|
||||||
req.mailArray[v[0]]=v[1]
|
|
||||||
})
|
|
||||||
if(!r.details.ldap_bindDN||r.details.ldap_bindDN===''){
|
|
||||||
r.details.ldap_bindDN=req.body.mail
|
|
||||||
}
|
|
||||||
if(!r.details.ldap_bindCredentials||r.details.ldap_bindCredentials===''){
|
|
||||||
r.details.ldap_bindCredentials=req.body.pass
|
|
||||||
}
|
|
||||||
if(!r.details.ldap_searchFilter||r.details.ldap_searchFilter===''){
|
|
||||||
r.details.ldap_searchFilter=req.body.mail
|
|
||||||
if(req.mailArray.cn){
|
|
||||||
r.details.ldap_searchFilter='cn='+req.mailArray.cn
|
|
||||||
}
|
|
||||||
if(req.mailArray.uid){
|
|
||||||
r.details.ldap_searchFilter='uid='+req.mailArray.uid
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
r.details.ldap_searchFilter=r.details.ldap_searchFilter.replace('{{username}}',req.body.mail)
|
|
||||||
}
|
|
||||||
if(!r.details.ldap_searchBase||r.details.ldap_searchBase===''){
|
|
||||||
r.details.ldap_searchBase='dc=test,dc=com'
|
|
||||||
}
|
|
||||||
req.auth = new LdapAuth({
|
|
||||||
url:r.details.ldap_url,
|
|
||||||
bindDN:r.details.ldap_bindDN,
|
|
||||||
bindCredentials:r.details.ldap_bindCredentials,
|
|
||||||
searchBase:r.details.ldap_searchBase,
|
|
||||||
searchFilter:'('+r.details.ldap_searchFilter+')',
|
|
||||||
reconnect:true
|
|
||||||
});
|
|
||||||
req.auth.on('error', function (err) {
|
|
||||||
console.error('LdapAuth: ', err);
|
|
||||||
});
|
|
||||||
|
|
||||||
req.auth.authenticate(req.body.mail, req.body.pass, function(err, user) {
|
|
||||||
if(user){
|
|
||||||
//found user
|
|
||||||
if(!user.uid){
|
|
||||||
user.uid=s.gid()
|
|
||||||
}
|
|
||||||
const userInfo = {
|
|
||||||
ke:req.body.key,
|
|
||||||
uid:user.uid,
|
|
||||||
auth:s.createHash(s.gid()),
|
|
||||||
mail:user.mail,
|
|
||||||
pass:s.createHash(req.body.pass),
|
|
||||||
details:JSON.stringify({
|
|
||||||
sub:'1',
|
|
||||||
ldap:'1',
|
|
||||||
allmonitors:'1',
|
|
||||||
filter: {}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
s.userLog({ke:req.body.key,mid:'$USER'},{type:r.lang['LDAP Success'],msg:{user:user}})
|
|
||||||
s.knexQuery({
|
|
||||||
action: "select",
|
|
||||||
columns: "*",
|
|
||||||
table: "Users",
|
|
||||||
where: [
|
|
||||||
['ke','=',req.body.key],
|
|
||||||
['mail','=',user.cn],
|
|
||||||
],
|
|
||||||
},function(err,rr) {
|
|
||||||
if(rr&&rr[0]){
|
|
||||||
//already registered
|
|
||||||
rr = rr[0]
|
|
||||||
userInfo = rr;
|
|
||||||
rr.details = JSON.parse(rr.details)
|
|
||||||
userInfo.lang = s.getLanguageFile(rr.details.lang)
|
|
||||||
s.userLog({ke:req.body.key,mid:'$USER'},{type:r.lang['LDAP User Authenticated'],msg:{user:user,shinobiUID:rr.uid}})
|
|
||||||
s.knexQuery({
|
|
||||||
action: "update",
|
|
||||||
table: "Users",
|
|
||||||
update: {
|
|
||||||
auth: userInfo.auth
|
|
||||||
},
|
|
||||||
where: [
|
|
||||||
['ke','=',userInfo.ke],
|
|
||||||
['uid','=',rr.uid],
|
|
||||||
]
|
|
||||||
})
|
|
||||||
}else{
|
|
||||||
//new ldap login
|
|
||||||
s.userLog({ke:req.body.key,mid:'$USER'},{type:r.lang['LDAP User is New'],msg:{info:r.lang['Creating New Account'],user:user}})
|
|
||||||
userInfo.lang = r.lang
|
|
||||||
s.knexQuery({
|
|
||||||
action: "insert",
|
|
||||||
table: "Users",
|
|
||||||
insert: userInfo,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
userInfo.details = JSON.stringify(userInfo.details)
|
|
||||||
userInfo.auth_token = userInfo.auth
|
|
||||||
userInfo.ok = true
|
|
||||||
checkRoute(req.body.function,userInfo)
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
s.userLog({ke:req.body.key,mid:'$USER'},{type:r.lang['LDAP Failed'],msg:{err:err}})
|
|
||||||
//no user
|
|
||||||
regularLogin()
|
|
||||||
});
|
|
||||||
|
|
||||||
req.auth.close(function(err) {
|
|
||||||
|
|
||||||
})
|
|
||||||
}else{
|
|
||||||
regularLogin()
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
regularLogin()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}else if(req.body.function === 'super'){
|
|
||||||
const superLoginResponse = await superLogin(req.body.mail,req.body.pass);
|
const superLoginResponse = await superLogin(req.body.mail,req.body.pass);
|
||||||
if(superLoginResponse.ok){
|
if(superLoginResponse.ok){
|
||||||
renderPage(config.renderPaths.super,{
|
renderPage(config.renderPaths.super,{
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -27,7 +27,7 @@
|
||||||
"http-proxy": "^1.17.0",
|
"http-proxy": "^1.17.0",
|
||||||
"jsonfile": "^3.0.1",
|
"jsonfile": "^3.0.1",
|
||||||
"knex": "^0.21.4",
|
"knex": "^0.21.4",
|
||||||
"ldapauth-fork": "^4.3.3",
|
"ldapauth-fork": "^5.0.1",
|
||||||
"moment": "^2.27.0",
|
"moment": "^2.27.0",
|
||||||
"mp4frag": "^0.2.0",
|
"mp4frag": "^0.2.0",
|
||||||
"mysql": "^2.18.1",
|
"mysql": "^2.18.1",
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,41 @@
|
||||||
|
// const { authenticate } = require('ldap-authentication')
|
||||||
|
//
|
||||||
|
// async function runTest(){
|
||||||
|
// try{
|
||||||
|
// let authenticated = await authenticate({
|
||||||
|
// ldapOpts: { url: 'ldap://127.0.0.1:389' },
|
||||||
|
// userDn: 'uid=ubuntu,dc=example,dc=com',
|
||||||
|
// userPassword: 'moeiscool',
|
||||||
|
// userSearchBase: 'dc=example,dc=com',
|
||||||
|
// usernameAttribute: 'uid',
|
||||||
|
// username: 'ubuntu2',
|
||||||
|
// })
|
||||||
|
// console.log(authenticated)
|
||||||
|
// }catch(err){
|
||||||
|
// console.log('Login Error')
|
||||||
|
// console.log(err)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// runTest()
|
||||||
|
|
||||||
|
var LdapAuth = require('ldapauth-fork');
|
||||||
|
|
||||||
|
const host = 'ldap://127.0.0.1:389'
|
||||||
|
const username = 'ubuntu2'
|
||||||
|
const password = 'moeiscool'
|
||||||
|
const bindDN = 'uid=ubuntu2,ou=People,dc=example,dc=com'
|
||||||
|
const searchBase = 'ou=People,dc=example,dc=com'
|
||||||
|
const searchFilter = '(uid={{username}})'
|
||||||
|
|
||||||
|
const ldap = new LdapAuth({
|
||||||
|
url: host,
|
||||||
|
bindDN: bindDN,
|
||||||
|
bindCredentials: password,
|
||||||
|
searchBase: searchBase,
|
||||||
|
searchFilter: searchFilter,
|
||||||
|
reconnect: true
|
||||||
|
})
|
||||||
|
|
||||||
|
ldap.authenticate(username, password, function(err, user) {
|
||||||
|
console.log(err,user)
|
||||||
|
})
|
||||||
|
|
@ -6,17 +6,19 @@ $(document).ready(function(){
|
||||||
alternateLoginsBox.empty()
|
alternateLoginsBox.empty()
|
||||||
if(rows.length > 0){
|
if(rows.length > 0){
|
||||||
$.each(rows,function(n,row){
|
$.each(rows,function(n,row){
|
||||||
alternateLoginsBox.append(`<div class="row" login-id="${row.loginId}">
|
alternateLoginsBox.append(`<div class="row" login-id="${row.loginId}" style="border-bottom: 1px solid #333;padding-top:1rem;padding-bottom:1rem;display:flex">
|
||||||
<div class="col-md-4" style="text-transform:capitalize;font-size: 150%;">
|
<div class="col-md-3" style="flex: 3">
|
||||||
<i class="fa fa-${row.type}"></i>
|
<i class="fa fa-address-card"></i>
|
||||||
<span>${row.type}</span>
|
<span class="epic-text text-white">${row.type}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-4">
|
<div class="col-md-3" style="flex: 3">
|
||||||
<div>${row.name}</div>
|
<div>${row.name}</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-3" style="flex: 3">
|
||||||
<div title="${lang.lastLogin}">${moment(row.lastLogin).format('YYYY-MM-DD hh:mm:ss A')}</div>
|
<div title="${lang.lastLogin}">${moment(row.lastLogin).format('YYYY-MM-DD hh:mm:ss A')}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-4 text-right">
|
<div class="col-md-3 text-right" style="flex: 3">
|
||||||
<a class="btn btn-sm btn-danger unlink-account"><i class="fa fa-unlink"></i> ${lang.Unlink}</a>
|
<a class="btn badge-sm badge btn-danger unlink-account"><i class="fa fa-unlink"></i> ${lang.Unlink}</a>
|
||||||
</div>
|
</div>
|
||||||
</div>`)
|
</div>`)
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
$(document).ready(function(){
|
||||||
|
$('#settings').on('click','.ldap-sign-in',function(){
|
||||||
|
var signInWindow = window.open(getApiPrefix('loginTokenAddLDAP'),'popup','width=500,height=700,scrollbars=no,resizable=no');
|
||||||
|
if(!signInWindow || signInWindow.closed || typeof signInWindow.closed=='undefined'){
|
||||||
|
alert(`Your Popup Blocker is disabling this feature.`)
|
||||||
|
}else{
|
||||||
|
signInWindow.onbeforeunload = function(){
|
||||||
|
drawAlternateLoginsToSettings()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
@ -144,6 +144,22 @@ drawBlock = function(monitorSettings){
|
||||||
var fieldElement = ''
|
var fieldElement = ''
|
||||||
var preFill = field.preFill || ''
|
var preFill = field.preFill || ''
|
||||||
switch(fieldType){
|
switch(fieldType){
|
||||||
|
case'btn-group':
|
||||||
|
let fieldBtnContent = ``
|
||||||
|
field.btns.forEach((btn) => {
|
||||||
|
let btnClass = []
|
||||||
|
let btnAttributes = []
|
||||||
|
const btnBaseElement = btn.forForm || field.forForm ? 'button' : 'a'
|
||||||
|
if(btn.class){
|
||||||
|
btnClass.push(`${btn.class}`)
|
||||||
|
}
|
||||||
|
if(btn.attribute){
|
||||||
|
btnAttributes.push(btn.attribute)
|
||||||
|
}
|
||||||
|
fieldBtnContent += `<${btnBaseElement} class="btn ${btnClass.join(' ')}" ${btnAttributes.join(' ')}>${btn.btnContent}</${btnBaseElement}>`
|
||||||
|
})
|
||||||
|
fieldElement = `<div class="btn-group btn-group-justified ${fieldClass.join(' ')}" ${attributes.join(' ')}>${fieldBtnContent}</div>`
|
||||||
|
break;
|
||||||
case'btn':
|
case'btn':
|
||||||
baseElement = field.forForm ? 'button' : 'a'
|
baseElement = field.forForm ? 'button' : 'a'
|
||||||
fieldElement = `<${baseElement} class="btn btn-block ${fieldClass.join(' ')}" ${attributes.join(' ')}>${field.btnContent}</${baseElement}>`
|
fieldElement = `<${baseElement} class="btn btn-block ${fieldClass.join(' ')}" ${attributes.join(' ')}>${field.btnContent}</${baseElement}>`
|
||||||
|
|
@ -190,7 +206,7 @@ drawBlock = function(monitorSettings){
|
||||||
if(field['form-group-class-pre-layer']){ %>
|
if(field['form-group-class-pre-layer']){ %>
|
||||||
<div class="<%- field['form-group-class-pre-layer'] %>">
|
<div class="<%- field['form-group-class-pre-layer'] %>">
|
||||||
<% }
|
<% }
|
||||||
if(fieldType === 'ul' || fieldType === 'div' || fieldType === 'btn' || fieldType === 'table' || fieldType === 'form'){ %>
|
if(fieldType === 'ul' || fieldType === 'div' || fieldType === 'btn' || fieldType === 'btn-group' || fieldType === 'table' || fieldType === 'form'){ %>
|
||||||
<%- fieldElement %>
|
<%- fieldElement %>
|
||||||
<% }else{ %>
|
<% }else{ %>
|
||||||
<div <%- hidden %> class="form-group <%- field['form-group-class'] %>">
|
<div <%- hidden %> class="form-group <%- field['form-group-class'] %>">
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,48 @@
|
||||||
|
<%
|
||||||
|
details = $user.details
|
||||||
|
window.libURL = originalURL + global.s.checkCorrectPathEnding(config.webPaths.home)
|
||||||
|
%>
|
||||||
|
<link rel="stylesheet" href="<%-window.libURL%>libs/css/bootstrap4.min.css" />
|
||||||
|
<link rel="stylesheet" href="<%-window.libURL%>libs/css/dash2.basic.css">
|
||||||
|
<link rel="stylesheet" href="<%-window.libURL%>libs/css/dash2.forms.css">
|
||||||
|
<script src="<%-window.libURL%>libs/js/jquery.min.js"></script>
|
||||||
|
<script src="<%-window.libURL%>libs/js/jquery.serialize.js"></script>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
background: #333;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<%
|
||||||
|
var drawBlock
|
||||||
|
var buildOptions
|
||||||
|
%>
|
||||||
|
<form class="dark">
|
||||||
|
<%
|
||||||
|
include fieldBuilders.ejs
|
||||||
|
%>
|
||||||
|
<%
|
||||||
|
drawBlock(define['LDAP'].blocks.LDAP)
|
||||||
|
%>
|
||||||
|
</form>
|
||||||
|
<script>
|
||||||
|
$(document).ready(function() {
|
||||||
|
var theForm = $('form')
|
||||||
|
theForm.submit(function(e) {
|
||||||
|
e.preventDefault()
|
||||||
|
console.log('Logged in to LDAP! Binding...')
|
||||||
|
$.post(location.href,theForm.serializeObject(),function(data){
|
||||||
|
if(data.ok){
|
||||||
|
window.close()
|
||||||
|
}else{
|
||||||
|
console.log(data)
|
||||||
|
$('.monitor-section-header ').html(data.msg || 'Failed to Save').css({
|
||||||
|
color: "#fff",
|
||||||
|
textAlign: "center",
|
||||||
|
fontFamily: "monospace",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return false;
|
||||||
|
})
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
@ -30,224 +30,11 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<%
|
<%
|
||||||
var buildOptions = function(field,possiblities){
|
var drawBlock
|
||||||
if(!field)console.error('field',field)
|
var buildOptions
|
||||||
var fieldElement = ''
|
|
||||||
possiblities.forEach(function(option){
|
|
||||||
if(option.optgroup){
|
|
||||||
fieldElement += '<optgroup label="' + option.name + '">'
|
|
||||||
fieldElement += buildOptions(field,option.optgroup)
|
|
||||||
fieldElement += '</optgroup>'
|
|
||||||
}else{
|
|
||||||
var selected = ''
|
|
||||||
if(option.value === field.default){
|
|
||||||
selected = 'selected'
|
|
||||||
}
|
|
||||||
fieldElement += '<option value="' + option.value + '" ' + selected + '>' + option.name + '</option>'
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return fieldElement
|
|
||||||
}
|
|
||||||
var drawBlock = function(monitorSettings){
|
|
||||||
if(monitorSettings.evaluation && !eval(monitorSettings.evaluation)){
|
|
||||||
return
|
|
||||||
}
|
|
||||||
var attributes = []
|
|
||||||
var styles = []
|
|
||||||
var sectionClass = []
|
|
||||||
var headerTitle = monitorSettings.headerTitle || lang[monitorSettings.name] || monitorSettings.name
|
|
||||||
if(monitorSettings.hidden === true){
|
|
||||||
styles.push('display:none')
|
|
||||||
}
|
|
||||||
if(monitorSettings.style){
|
|
||||||
styles.push(monitorSettings.style)
|
|
||||||
}
|
|
||||||
if(monitorSettings.isSection === true){
|
|
||||||
attributes.push('section')
|
|
||||||
}
|
|
||||||
if(monitorSettings.attribute){
|
|
||||||
attributes.push(monitorSettings.attribute)
|
|
||||||
}
|
|
||||||
if(!monitorSettings.id){
|
|
||||||
var userSettingsId = monitorSettings.name.replace(/[^a-zA-Z ]/g, '').replace(/[^a-zA-Z ]/g, '').replace(/ /g, '')
|
|
||||||
monitorSettings.id = userSettingsId
|
|
||||||
}
|
|
||||||
attributes.push(`id="${monitorSettings.id}"`)
|
|
||||||
if(monitorSettings.color){
|
|
||||||
sectionClass.push(monitorSettings.color)
|
|
||||||
}
|
|
||||||
if(monitorSettings['section-class']){
|
|
||||||
sectionClass.push(monitorSettings['section-class'])
|
|
||||||
}
|
|
||||||
if(monitorSettings.isAdvanced){ %>
|
|
||||||
<div class="h_us_input h_us_advanced" style="display:none">
|
|
||||||
<% }
|
|
||||||
if(monitorSettings['section-pre-pre-class']){ %>
|
|
||||||
<div class="<%- monitorSettings['section-pre-pre-class'] %>">
|
|
||||||
<% }
|
|
||||||
if(monitorSettings['section-pre-class']){ %>
|
|
||||||
<div class="<%- monitorSettings['section-pre-class'] %>">
|
|
||||||
<% }
|
|
||||||
%>
|
%>
|
||||||
<div <%- attributes.join(' ') %> style="<%- styles.join(';') %>" class="form-group-group <%- sectionClass.join(' ') %>">
|
|
||||||
<h4 class="monitor-section-header <%- monitorSettings.headerClass %>"><%- headerTitle %>
|
|
||||||
<% if(monitorSettings.headerButtons){ %>
|
|
||||||
<div class="pull-right">
|
|
||||||
<% monitorSettings.headerButtons.forEach(function(button){ %>
|
|
||||||
<a class="btn btn-success btn-xs <%- button.class %>">
|
|
||||||
<% if(button.icon){ %><i class="fa fa-<%- button.icon %>"></i><% } %>
|
|
||||||
<% if(button.text){ %><%- button.text %><% } %>
|
|
||||||
</a>
|
|
||||||
<% }) %>
|
|
||||||
</div>
|
|
||||||
<% } %>
|
|
||||||
</h4>
|
|
||||||
<div class="box-wrapper">
|
|
||||||
<% if(monitorSettings['input-mapping']){ %>
|
|
||||||
<div class="form-group-group forestgreen" style="display:none" input-mapping="<%- monitorSettings['input-mapping'] %>">
|
|
||||||
<h4><%-lang['Input Feed']%>
|
|
||||||
<div class="pull-right">
|
|
||||||
<a class="btn btn-success btn-xs add_map_row"><i class="fa fa-plus-square-o"></i></a>
|
|
||||||
</div>
|
|
||||||
</h4>
|
|
||||||
<div class="choices"></div>
|
|
||||||
</div>
|
|
||||||
<% } %>
|
|
||||||
<% if(monitorSettings.blockquote){ %>
|
|
||||||
<blockquote class="<%- monitorSettings.blockquoteClass || '' %>">
|
|
||||||
<%- monitorSettings.blockquote %>
|
|
||||||
</blockquote>
|
|
||||||
<% } %>
|
|
||||||
<% if(monitorSettings.blocks){
|
|
||||||
monitorSettings.blocks.forEach(function(settingsBlock){
|
|
||||||
drawBlock(settingsBlock)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
if(monitorSettings.info){
|
|
||||||
monitorSettings.info.forEach(function(field){
|
|
||||||
if(field.isFormGroupGroup === true){
|
|
||||||
drawBlock(field)
|
|
||||||
}else{
|
|
||||||
if(field.notForSubAccount === true){
|
|
||||||
var notForSubAccount = '!details.sub'
|
|
||||||
if(!field.evaluation){
|
|
||||||
field.evaluation = notForSubAccount
|
|
||||||
}else{
|
|
||||||
field.evaluation += ' && ' + notForSubAccount
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(field.evaluation && !eval(field.evaluation)){
|
|
||||||
return
|
|
||||||
}
|
|
||||||
var hidden = ''
|
|
||||||
if(field.hidden === true){
|
|
||||||
hidden = 'style="display:none"'
|
|
||||||
}
|
|
||||||
var fieldClass = []
|
|
||||||
var attributes = []
|
|
||||||
if(field.name && field.name.indexOf('detail=') > -1){
|
|
||||||
attributes.push(field.name)
|
|
||||||
}else if(field.name){
|
|
||||||
attributes.push("name=" + field.name)
|
|
||||||
}
|
|
||||||
if(field.placeholder || field.default){
|
|
||||||
attributes.push(`placeholder="${field.placeholder || field.default}"`)
|
|
||||||
}else if(field.example){
|
|
||||||
attributes.push(`placeholder="Example : ${field.example}"`)
|
|
||||||
}
|
|
||||||
if(field.attribute){
|
|
||||||
attributes.push(field.attribute)
|
|
||||||
}
|
|
||||||
if(field.selector){
|
|
||||||
attributes.push(`selector="${field.selector}"`)
|
|
||||||
}
|
|
||||||
if(field.id){
|
|
||||||
attributes.push(`id="${field.id}"`)
|
|
||||||
}
|
|
||||||
if(field.class){
|
|
||||||
fieldClass.push(`${field.class}`)
|
|
||||||
}
|
|
||||||
var possiblities = field.possible || []
|
|
||||||
var fieldType = field.fieldType || 'text'
|
|
||||||
var fieldElement = ''
|
|
||||||
var preFill = field.preFill || ''
|
|
||||||
switch(fieldType){
|
|
||||||
case'btn':
|
|
||||||
|
|
||||||
fieldElement = `<a class="btn btn-block ${fieldClass.join(' ')}" ${attributes.join(' ')}>${field.btnContent}</a>`
|
|
||||||
break;
|
|
||||||
case'ul':
|
|
||||||
fieldElement = `<ul ${attributes.join(' ')} class="${fieldClass.join(' ')}" ></ul>`
|
|
||||||
break;
|
|
||||||
case'div':
|
|
||||||
fieldElement = `<div ${attributes.join(' ')} class="${fieldClass.join(' ')}" ></div>`
|
|
||||||
break;
|
|
||||||
case'number':
|
|
||||||
if(field.numberMin){
|
|
||||||
attributes.push(`min="${field.numberMin}"`)
|
|
||||||
}
|
|
||||||
if(field.numberMax){
|
|
||||||
attributes.push(`max="${field.numberMax}"`)
|
|
||||||
}
|
|
||||||
fieldElement = '<div><input type="number" class="form-control" ' + attributes.join(' ') + '></div>'
|
|
||||||
break;
|
|
||||||
case'password':
|
|
||||||
fieldElement = '<div><input type="password" class="form-control" ' + attributes.join(' ') + '></div>'
|
|
||||||
break;
|
|
||||||
case'text':
|
|
||||||
fieldElement = `<div><input class="form-control" ${attributes.join(' ')} value="${preFill}"></div>`
|
|
||||||
break;
|
|
||||||
case'textarea':
|
|
||||||
fieldElement = '<div><textarea class="form-control" ' + attributes.join(' ') + '></textarea></div>'
|
|
||||||
break;
|
|
||||||
case'select':
|
|
||||||
fieldElement = '<div><select class="form-control" ' + attributes.join(' ') + '>'
|
|
||||||
fieldElement += buildOptions(field,possiblities)
|
|
||||||
fieldElement += '</select></div>'
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if(field['form-group-class-pre-pre-layer']){ %>
|
|
||||||
<div class="<%- field['form-group-class-pre-pre-layer'] %>">
|
|
||||||
<% }
|
|
||||||
if(field['form-group-class-pre-layer']){ %>
|
|
||||||
<div class="<%- field['form-group-class-pre-layer'] %>">
|
|
||||||
<% }
|
|
||||||
if(fieldType === 'ul' || fieldType === 'div' || fieldType === 'btn'){ %>
|
|
||||||
<%- fieldElement %>
|
|
||||||
<% }else{ %>
|
|
||||||
<div <%- hidden %> class="form-group <%- field['form-group-class'] %>">
|
|
||||||
<label><div><span><%- field.field %>
|
|
||||||
<% if(field.description){ %>
|
|
||||||
<small><%- field.description %></small>
|
|
||||||
<% } %>
|
|
||||||
</span></div>
|
|
||||||
<%- fieldElement %>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<% }
|
|
||||||
}
|
|
||||||
if(field['form-group-class-pre-layer']){ %>
|
|
||||||
</div>
|
|
||||||
<% }
|
|
||||||
if(field['form-group-class-pre-pre-layer']){ %>
|
|
||||||
</div>
|
|
||||||
<% }
|
|
||||||
})
|
|
||||||
}
|
|
||||||
%>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<%
|
<%
|
||||||
if(monitorSettings['section-pre-class']){ %>
|
include fieldBuilders.ejs
|
||||||
</div>
|
|
||||||
<% }
|
|
||||||
if(monitorSettings['section-pre-pre-class']){ %>
|
|
||||||
</div>
|
|
||||||
<% }
|
|
||||||
if(monitorSettings.isAdvanced){ %>
|
|
||||||
</div>
|
|
||||||
<% }
|
|
||||||
}
|
|
||||||
%>
|
%>
|
||||||
<% Object.keys(define['Account Settings'].blocks).forEach(function(blockKey){
|
<% Object.keys(define['Account Settings'].blocks).forEach(function(blockKey){
|
||||||
var accountSettings = define['Account Settings'].blocks[blockKey]
|
var accountSettings = define['Account Settings'].blocks[blockKey]
|
||||||
|
|
|
||||||
|
|
@ -81,18 +81,11 @@
|
||||||
<div class="form-group f_i_input f_i_ldap" style="display:none">
|
<div class="form-group f_i_input f_i_ldap" style="display:none">
|
||||||
<input name="key" id="key" tabindex="2" class="monospace form-control wide-text" placeholder="Group Key">
|
<input name="key" id="key" tabindex="2" class="monospace form-control wide-text" placeholder="Group Key">
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group" style="display:none">
|
|
||||||
<select class="form-control wide-text" name="alternateLogin">
|
|
||||||
<option value="" selected>Default</option>
|
|
||||||
<option value="google">Google</option>
|
|
||||||
</select>
|
|
||||||
<input style="display:none" name="alternateLoginToken" class="monospace form-control wide-text" placeholder="Group Key">
|
|
||||||
</div>
|
|
||||||
<% if(config.showLoginSelector === true){ %>
|
<% if(config.showLoginSelector === true){ %>
|
||||||
<div class="form-group">
|
<div class="form-group f_i_input f_i_">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-12 monospace">
|
<div class="col-md-12 monospace">
|
||||||
<select class="form-control wide-text" name="function" selector="f_i">
|
<select class="form-control wide-text" name="function">
|
||||||
<% switch(screen){
|
<% switch(screen){
|
||||||
case'super': %>
|
case'super': %>
|
||||||
<option value="super"><%- lang.Superuser %></option>
|
<option value="super"><%- lang.Superuser %></option>
|
||||||
|
|
@ -102,9 +95,6 @@
|
||||||
<% break;
|
<% break;
|
||||||
default: %>
|
default: %>
|
||||||
<option value="dash" selected><%- lang.Dashboard %></option>
|
<option value="dash" selected><%- lang.Dashboard %></option>
|
||||||
<% if(config.productType==='Pro'){ %>
|
|
||||||
<option value="ldap"><%- lang.LDAP %></option>
|
|
||||||
<% } %>
|
|
||||||
<option value="streamer"><%- lang.Streamer %></option>
|
<option value="streamer"><%- lang.Streamer %></option>
|
||||||
<option value="cam"><%- lang.Dashcam %> (<%- lang.Streamer %> v2)</option>
|
<option value="cam"><%- lang.Dashcam %> (<%- lang.Streamer %> v2)</option>
|
||||||
<% break;
|
<% break;
|
||||||
|
|
@ -129,6 +119,14 @@
|
||||||
</select>
|
</select>
|
||||||
<% } %>
|
<% } %>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
|
<select class="form-control wide-text" name="alternateLogin" selector="f_i">
|
||||||
|
<option value="" selected><%- lang.Default %></option>
|
||||||
|
<option value="google">Google</option>
|
||||||
|
<option value="ldap"><%- lang.LDAP %></option>
|
||||||
|
</select>
|
||||||
|
<input style="display:none" name="alternateLoginToken" class="monospace form-control wide-text" placeholder="Group Key">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
<button type="submit" name="login-submit" id="login-submit" tabindex="4" class="btn btn-success btn-block wide-text" style="color:#FFF"><i class="fa fa-key"></i> <%- lang.Login %></button>
|
<button type="submit" name="login-submit" id="login-submit" tabindex="4" class="btn btn-success btn-block wide-text" style="color:#FFF"><i class="fa fa-key"></i> <%- lang.Login %></button>
|
||||||
</div>
|
</div>
|
||||||
<% if(config.allowGoogleSignOn){ %>
|
<% if(config.allowGoogleSignOn){ %>
|
||||||
|
|
@ -233,7 +231,7 @@ $('[selector]').change(function(e){
|
||||||
<script>
|
<script>
|
||||||
function onGoogleSignIn(googleUser) {
|
function onGoogleSignIn(googleUser) {
|
||||||
var id_token = googleUser.getAuthResponse().id_token;
|
var id_token = googleUser.getAuthResponse().id_token;
|
||||||
$.ccio.f.find('[name="mail"],[name="pass"],.g-signin2').hide()
|
$.ccio.f.find('[name="mail"],[name="pass"],[name="alternateLogin"],.g-signin2').hide()
|
||||||
$.ccio.f.find('[name="alternateLogin"]').val('google')
|
$.ccio.f.find('[name="alternateLogin"]').val('google')
|
||||||
$.ccio.f.find('[name="alternateLoginToken"]').val(id_token)
|
$.ccio.f.find('[name="alternateLoginToken"]').val(id_token)
|
||||||
$.ccio.f.find('[name="login-submit"]').html(`<i class="fa fa-google"></i> <%- lang.Login %>`)
|
$.ccio.f.find('[name="login-submit"]').html(`<i class="fa fa-google"></i> <%- lang.Login %>`)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue