Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
openvpn-app
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
1
Issues
1
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Incidents
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
cloudron
openvpn-app
Commits
0cd54219
Commit
0cd54219
authored
Sep 24, 2020
by
Girish Ramakrishnan
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
sync coding style
parent
23785041
Changes
4
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
531 additions
and
531 deletions
+531
-531
frontend/index.html
frontend/index.html
+1
-1
server.js
server.js
+154
-154
src/ldap.js
src/ldap.js
+66
-66
src/openvpn.js
src/openvpn.js
+310
-310
No files found.
frontend/index.html
View file @
0cd54219
...
...
@@ -102,7 +102,7 @@
<a
:href=
"'/api/key/' + scope.row.name + '?format=ovpn&zip=false'"
>
.ovpn - embedded certs
</a>
</el-dropdown-item>
<el-dropdown-item>
<a
:href=
"'/api/key/' + scope.row.name + '?format=tblk'"
>
.tblk
</a>
<a
:href=
"'/api/key/' + scope.row.name + '?format=tblk'"
>
.tblk
(For Tunnelblick)
</a>
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
...
...
server.js
View file @
0cd54219
#!/usr/bin/env node
'
use strict
'
const
express
=
require
(
'
express
'
)
const
morgan
=
require
(
'
morgan
'
)
const
path
=
require
(
'
path
'
)
const
compression
=
require
(
'
compression
'
)
const
ini
=
require
(
'
ini
'
)
const
session
=
require
(
'
express-session
'
)
const
lastMile
=
require
(
'
connect-lastmile
'
)
const
{
HttpSuccess
,
HttpError
}
=
require
(
'
connect-lastmile
'
)
const
ldap
=
require
(
'
./src/ldap
'
)
const
bodyParser
=
require
(
'
body-parser
'
)
const
fs
=
require
(
'
fs
'
)
const
openvpn
=
require
(
'
./src/openvpn
'
)
const
LokiStore
=
require
(
'
connect-loki
'
)(
session
)
'
use strict
'
;
const
express
=
require
(
'
express
'
)
;
const
morgan
=
require
(
'
morgan
'
)
;
const
path
=
require
(
'
path
'
)
;
const
compression
=
require
(
'
compression
'
)
;
const
ini
=
require
(
'
ini
'
)
;
const
session
=
require
(
'
express-session
'
)
;
const
lastMile
=
require
(
'
connect-lastmile
'
)
;
const
{
HttpSuccess
,
HttpError
}
=
require
(
'
connect-lastmile
'
)
;
const
ldap
=
require
(
'
./src/ldap
'
)
;
const
bodyParser
=
require
(
'
body-parser
'
)
;
const
fs
=
require
(
'
fs
'
)
;
const
openvpn
=
require
(
'
./src/openvpn
'
)
;
const
LokiStore
=
require
(
'
connect-loki
'
)(
session
)
;
const
execSync
=
require
(
'
child_process
'
).
execSync
;
const
app
=
express
()
const
router
=
new
express
.
Router
()
const
app
=
express
()
;
const
router
=
new
express
.
Router
()
;
const
urlEncodedParser
=
bodyParser
.
urlencoded
({
extended
:
true
})
const
jsonParser
=
bodyParser
.
json
({
strict
:
true
})
const
urlEncodedParser
=
bodyParser
.
urlencoded
({
extended
:
true
})
;
const
jsonParser
=
bodyParser
.
json
({
strict
:
true
})
;
const
baseDir
=
process
.
env
.
CLOUDRON
?
'
/app/data
'
:
path
.
join
(
__dirname
,
'
.dev/data
'
)
const
baseDir
=
process
.
env
.
CLOUDRON
?
'
/app/data
'
:
path
.
join
(
__dirname
,
'
.dev/data
'
)
;
// config is for app configs, settings is for openvpn settings
const
CONFIG_FILE_PATH
=
path
.
join
(
baseDir
,
'
config.ini
'
)
const
OPENVPN_SETTINGS_FILE_PATH
=
path
.
join
(
baseDir
,
'
openvpn.conf
'
)
const
CONFIG_FILE_PATH
=
path
.
join
(
baseDir
,
'
config.ini
'
)
;
const
OPENVPN_SETTINGS_FILE_PATH
=
path
.
join
(
baseDir
,
'
openvpn.conf
'
)
;
console
.
log
(
`Using app config file at
${
CONFIG_FILE_PATH
}
`
)
console
.
log
(
`Using OpenVPN settings file at
${
OPENVPN_SETTINGS_FILE_PATH
}
`
)
console
.
log
(
`Using app config file at
${
CONFIG_FILE_PATH
}
`
)
;
console
.
log
(
`Using OpenVPN settings file at
${
OPENVPN_SETTINGS_FILE_PATH
}
`
)
;
function
reloadConfig
()
{
let
config
=
{}
try
{
config
=
ini
.
parse
(
fs
.
readFileSync
(
CONFIG_FILE_PATH
,
'
utf-8
'
))
}
catch
(
e
)
{
console
.
log
(
'
No config file found, creating empty one
'
)
fs
.
writeFileSync
(
CONFIG_FILE_PATH
,
'
[roles]
\n
#admins=username1,username2
\n
'
)
}
config
.
roles
=
config
.
roles
||
{}
config
.
roles
.
admins
=
config
.
roles
.
admins
||
''
config
.
roles
.
admins
=
config
.
roles
.
admins
.
split
(
'
,
'
)
return
config
let
config
=
{};
try
{
config
=
ini
.
parse
(
fs
.
readFileSync
(
CONFIG_FILE_PATH
,
'
utf-8
'
));
}
catch
(
e
)
{
console
.
log
(
'
No config file found, creating empty one
'
);
fs
.
writeFileSync
(
CONFIG_FILE_PATH
,
'
[roles]
\n
#admins=username1,username2
\n
'
);
}
config
.
roles
=
config
.
roles
||
{};
config
.
roles
.
admins
=
config
.
roles
.
admins
||
''
;
config
.
roles
.
admins
=
config
.
roles
.
admins
.
split
(
'
,
'
);
return
config
;
}
let
config
=
reloadConfig
()
let
config
=
reloadConfig
()
;
// This only fetches the settings supported by the UI
function
getOpenVPNSetting
()
{
let
settings
=
{}
// this crashes the app intentionally to restart it and let it create a default
let
tmp
=
''
try
{
tmp
=
fs
.
readFileSync
(
OPENVPN_SETTINGS_FILE_PATH
,
'
utf-8
'
)
}
catch
(
e
)
{
console
.
error
(
e
)
process
.
exit
(
1
)
}
// ignore comments and empty lines
tmp
=
tmp
.
split
(
'
\n
'
).
map
((
l
)
=>
{
return
l
.
trim
()
})
tmp
=
tmp
.
filter
((
l
)
=>
{
return
l
&&
l
[
0
]
!==
'
#
'
})
function
findItem
(
prefix
)
{
let
idx
=
tmp
.
findIndex
((
l
)
=>
{
return
l
.
indexOf
(
prefix
)
===
0
})
if
(
idx
===
-
1
)
return
null
return
tmp
[
idx
].
slice
(
prefix
.
length
).
trim
().
replace
(
/
[
"
]
+$/g
,
''
)
}
settings
.
address
=
findItem
(
'
server
'
).
split
(
'
'
)[
0
];
settings
.
netmask
=
findItem
(
'
server
'
).
split
(
'
'
)[
1
];
settings
.
dnsServer
=
findItem
(
'
push "dhcp-option DNS
'
)
settings
.
allowICC
=
findItem
(
'
client-to-client
'
)
!==
null
return
settings
let
settings
=
{};
// this crashes the app intentionally to restart it and let it create a default
let
tmp
=
''
;
try
{
tmp
=
fs
.
readFileSync
(
OPENVPN_SETTINGS_FILE_PATH
,
'
utf-8
'
);
}
catch
(
e
)
{
console
.
error
(
e
);
process
.
exit
(
1
);
}
// ignore comments and empty lines
tmp
=
tmp
.
split
(
'
\n
'
).
map
((
l
)
=>
{
return
l
.
trim
();
});
tmp
=
tmp
.
filter
((
l
)
=>
{
return
l
&&
l
[
0
]
!==
'
#
'
;
});
function
findItem
(
prefix
)
{
let
idx
=
tmp
.
findIndex
((
l
)
=>
{
return
l
.
indexOf
(
prefix
)
===
0
;
});
if
(
idx
===
-
1
)
return
null
;
return
tmp
[
idx
].
slice
(
prefix
.
length
).
trim
().
replace
(
/
[
"
]
+$/g
,
''
);
}
settings
.
address
=
findItem
(
'
server
'
).
split
(
'
'
)[
0
];
settings
.
netmask
=
findItem
(
'
server
'
).
split
(
'
'
)[
1
];
settings
.
dnsServer
=
findItem
(
'
push "dhcp-option DNS
'
);
settings
.
allowICC
=
findItem
(
'
client-to-client
'
)
!==
null
;
return
settings
;
}
// This only fetches the settings supported by the UI
function
setOpenVPNSetting
(
settings
)
{
// this crashes the app intentionally to restart it and let it create a default
let
tmp
=
''
try
{
tmp
=
fs
.
readFileSync
(
OPENVPN_SETTINGS_FILE_PATH
,
'
utf-8
'
)
}
catch
(
e
)
{
console
.
error
(
e
)
process
.
exit
(
1
)
}
tmp
=
tmp
.
split
(
'
\n
'
)
// allowICC
let
idx
=
tmp
.
findIndex
((
l
)
=>
{
return
l
.
indexOf
(
'
client-to-client
'
)
!==
-
1
})
let
value
=
(
settings
.
allowICC
?
''
:
'
#
'
)
+
'
client-to-client
'
if
(
idx
===
-
1
)
tmp
.
push
(
value
)
else
tmp
[
idx
]
=
value
// server
idx
=
tmp
.
findIndex
((
l
)
=>
{
return
l
.
indexOf
(
'
server
'
)
!==
-
1
})
value
=
`server
${
settings
.
address
}
${
settings
.
netmask
}
`
if
(
idx
===
-
1
)
tmp
.
push
(
value
)
else
tmp
[
idx
]
=
value
// dnsServer
idx
=
tmp
.
findIndex
((
l
)
=>
{
return
l
.
indexOf
(
'
push "dhcp-option DNS
'
)
!==
-
1
})
value
=
`push "dhcp-option DNS
${
settings
.
dnsServer
}
"`
if
(
idx
===
-
1
)
tmp
.
push
(
value
)
else
tmp
[
idx
]
=
value
fs
.
writeFileSync
(
OPENVPN_SETTINGS_FILE_PATH
,
tmp
.
join
(
'
\n
'
),
'
utf-8
'
)
// this crashes the app intentionally to restart it and let it create a default
let
tmp
=
''
;
try
{
tmp
=
fs
.
readFileSync
(
OPENVPN_SETTINGS_FILE_PATH
,
'
utf-8
'
);
}
catch
(
e
)
{
console
.
error
(
e
);
process
.
exit
(
1
);
}
tmp
=
tmp
.
split
(
'
\n
'
);
// allowICC
let
idx
=
tmp
.
findIndex
((
l
)
=>
{
return
l
.
indexOf
(
'
client-to-client
'
)
!==
-
1
;
});
let
value
=
(
settings
.
allowICC
?
''
:
'
#
'
)
+
'
client-to-client
'
;
if
(
idx
===
-
1
)
tmp
.
push
(
value
);
else
tmp
[
idx
]
=
value
;
// server
idx
=
tmp
.
findIndex
((
l
)
=>
{
return
l
.
indexOf
(
'
server
'
)
!==
-
1
;
});
value
=
`server
${
settings
.
address
}
${
settings
.
netmask
}
`
;
if
(
idx
===
-
1
)
tmp
.
push
(
value
);
else
tmp
[
idx
]
=
value
;
// dnsServer
idx
=
tmp
.
findIndex
((
l
)
=>
{
return
l
.
indexOf
(
'
push "dhcp-option DNS
'
)
!==
-
1
;
});
value
=
`push "dhcp-option DNS
${
settings
.
dnsServer
}
"`
;
if
(
idx
===
-
1
)
tmp
.
push
(
value
);
else
tmp
[
idx
]
=
value
;
fs
.
writeFileSync
(
OPENVPN_SETTINGS_FILE_PATH
,
tmp
.
join
(
'
\n
'
),
'
utf-8
'
);
}
function
restartOpenVPN
()
{
...
...
@@ -124,60 +124,60 @@ function restartOpenVPN() {
return
null
;
}
const
isAuthenticated
=
(
req
,
res
,
next
)
=>
(
req
.
session
&&
req
.
session
.
user
)
?
next
()
:
res
.
status
(
401
).
send
({})
const
isAuthenticated
=
(
req
,
res
,
next
)
=>
(
req
.
session
&&
req
.
session
.
user
)
?
next
()
:
res
.
status
(
401
).
send
({})
;
app
.
use
(
'
/api/healthcheck
'
,
(
req
,
res
)
=>
openvpn
.
isRunning
()
.
then
(
running
=>
running
?
res
.
status
(
200
).
send
()
:
res
.
status
(
500
).
send
())
)
.
then
(
running
=>
running
?
res
.
status
(
200
).
send
()
:
res
.
status
(
500
).
send
())
)
;
app
.
set
(
'
trust proxy
'
,
1
)
app
.
use
(
morgan
(
'
dev
'
))
app
.
use
(
compression
())
app
.
set
(
'
trust proxy
'
,
1
)
;
app
.
use
(
morgan
(
'
dev
'
))
;
app
.
use
(
compression
())
;
app
.
use
(
session
({
secret
:
fs
.
readFileSync
(
path
.
resolve
(
__dirname
,
`
${
baseDir
}
/session.secret`
),
'
utf8
'
),
store
:
new
LokiStore
({
path
:
path
.
resolve
(
__dirname
,
`
${
baseDir
}
/session.db`
),
logErrors
:
true
}),
resave
:
false
,
saveUninitialized
:
false
,
name
:
'
openvpn.sid
'
,
cookie
:
{
path
:
'
/
'
,
httpOnly
:
true
,
secure
:
!!
process
.
env
.
CLOUDRON
,
maxAge
:
/* 1 week: */
7
/* d */
*
24
/* h */
*
60
/* min */
*
60
/* s */
*
1000
/* ms */
}
}))
secret
:
fs
.
readFileSync
(
path
.
resolve
(
__dirname
,
`
${
baseDir
}
/session.secret`
),
'
utf8
'
),
store
:
new
LokiStore
({
path
:
path
.
resolve
(
__dirname
,
`
${
baseDir
}
/session.db`
),
logErrors
:
true
}),
resave
:
false
,
saveUninitialized
:
false
,
name
:
'
openvpn.sid
'
,
cookie
:
{
path
:
'
/
'
,
httpOnly
:
true
,
secure
:
!!
process
.
env
.
CLOUDRON
,
maxAge
:
/* 1 week: */
7
/* d */
*
24
/* h */
*
60
/* min */
*
60
/* s */
*
1000
/* ms */
}
}))
;
router
.
post
(
'
/api/login
'
,
jsonParser
,
(
req
,
res
,
next
)
=>
{
if
(
!
req
.
body
.
username
||
!
req
.
body
.
password
)
{
req
.
session
.
user
=
null
next
(
new
HttpError
(
401
,
'
Unauthorized
'
))
}
else
{
ldap
.
auth
(
req
.
body
.
username
,
req
.
body
.
password
)
.
then
(
profile
=>
{
// on login check for new roles
config
=
reloadConfig
()
profile
.
isAdmin
=
config
.
roles
.
admins
.
indexOf
(
profile
.
username
)
!==
-
1
req
.
session
.
user
=
profile
next
(
new
HttpSuccess
(
200
,
{
user
:
req
.
session
.
user
}))
})
.
catch
(()
=>
next
(
new
HttpError
(
401
,
'
Unauthorized
'
)))
}
})
if
(
!
req
.
body
.
username
||
!
req
.
body
.
password
)
{
req
.
session
.
user
=
null
;
next
(
new
HttpError
(
401
,
'
Unauthorized
'
));
}
else
{
ldap
.
auth
(
req
.
body
.
username
,
req
.
body
.
password
)
.
then
(
profile
=>
{
// on login check for new roles
config
=
reloadConfig
();
profile
.
isAdmin
=
config
.
roles
.
admins
.
indexOf
(
profile
.
username
)
!==
-
1
;
req
.
session
.
user
=
profile
;
next
(
new
HttpSuccess
(
200
,
{
user
:
req
.
session
.
user
}));
})
.
catch
(()
=>
next
(
new
HttpError
(
401
,
'
Unauthorized
'
)));
}
})
;
router
.
get
(
'
/api/logout
'
,
(
req
,
res
)
=>
{
req
.
session
.
user
=
null
res
.
redirect
(
'
/
'
)
})
req
.
session
.
user
=
null
;
res
.
redirect
(
'
/
'
);
})
;
router
.
get
(
'
/api/profile
'
,
isAuthenticated
,
(
req
,
res
,
next
)
=>
{
next
(
new
HttpSuccess
(
200
,
{
user
:
req
.
session
.
user
}))
})
next
(
new
HttpSuccess
(
200
,
{
user
:
req
.
session
.
user
}));
})
;
router
.
get
(
'
/api/settings
'
,
isAuthenticated
,
(
req
,
res
,
next
)
=>
{
next
(
new
HttpSuccess
(
200
,
{
settings
:
getOpenVPNSetting
()
}))
})
next
(
new
HttpSuccess
(
200
,
{
settings
:
getOpenVPNSetting
()
}));
})
;
router
.
post
(
'
/api/settings
'
,
isAuthenticated
,
jsonParser
,
(
req
,
res
,
next
)
=>
{
setOpenVPNSetting
(
req
.
body
.
settings
);
...
...
@@ -189,19 +189,19 @@ router.post('/api/settings', isAuthenticated, jsonParser, (req, res, next) => {
next
(
new
HttpSuccess
(
201
,
{}));
});
router
.
post
(
'
/api/onConnect/
'
,
urlEncodedParser
,
openvpn
.
onClientConnect
)
router
.
post
(
'
/api/onDisconnect/
'
,
urlEncodedParser
,
openvpn
.
onClientDisconnect
)
router
.
post
(
'
/api/onLearnAddress/
'
,
urlEncodedParser
,
openvpn
.
onLearnAddress
)
router
.
get
(
'
/api/list/
'
,
isAuthenticated
,
openvpn
.
list
)
router
.
put
(
'
/api/key/*
'
,
isAuthenticated
,
openvpn
.
createKey
)
router
.
get
(
'
/api/key/*
'
,
isAuthenticated
,
openvpn
.
getKey
)
router
.
delete
(
'
/api/key/*
'
,
isAuthenticated
,
openvpn
.
revokeKey
)
app
.
use
(
router
)
app
.
use
(
'
/
'
,
express
.
static
(
path
.
resolve
(
__dirname
,
'
frontend
'
)))
app
.
use
(
lastMile
())
router
.
post
(
'
/api/onConnect/
'
,
urlEncodedParser
,
openvpn
.
onClientConnect
)
;
router
.
post
(
'
/api/onDisconnect/
'
,
urlEncodedParser
,
openvpn
.
onClientDisconnect
)
;
router
.
post
(
'
/api/onLearnAddress/
'
,
urlEncodedParser
,
openvpn
.
onLearnAddress
)
;
router
.
get
(
'
/api/list/
'
,
isAuthenticated
,
openvpn
.
list
)
;
router
.
put
(
'
/api/key/*
'
,
isAuthenticated
,
openvpn
.
createKey
)
;
router
.
get
(
'
/api/key/*
'
,
isAuthenticated
,
openvpn
.
getKey
)
;
router
.
delete
(
'
/api/key/*
'
,
isAuthenticated
,
openvpn
.
revokeKey
)
;
app
.
use
(
router
)
;
app
.
use
(
'
/
'
,
express
.
static
(
path
.
resolve
(
__dirname
,
'
frontend
'
)))
;
app
.
use
(
lastMile
())
;
const
server
=
app
.
listen
(
3000
,
'
0.0.0.0
'
,
()
=>
{
const
{
address
,
port
}
=
server
.
address
()
const
{
address
,
port
}
=
server
.
address
();
console
.
log
(
`OpenVPN web-config interface listening at http://
${
address
}
:
${
port
}
`
)
})
console
.
log
(
`OpenVPN web-config interface listening at http://
${
address
}
:
${
port
}
`
);
})
;
src/ldap.js
View file @
0cd54219
'
use strict
'
'
use strict
'
;
const
ldap
=
require
(
'
ldapjs
'
)
const
ldap
=
require
(
'
ldapjs
'
)
;
if
(
!
process
.
env
.
CLOUDRON_LDAP_URL
)
{
console
.
error
(
'
CLOUDRON_LDAP_URL not set. Cannot continue
'
)
process
.
exit
(
1
)
console
.
error
(
'
CLOUDRON_LDAP_URL not set. Cannot continue
'
);
process
.
exit
(
1
);
}
const
client
=
ldap
.
createClient
({
url
:
process
.
env
.
CLOUDRON_LDAP_URL
,
timeout
:
10000
,
/* 10 seconds */
reconnect
:
true
/* undocumented option to automatically reconnect on connection failure : https://github.com/joyent/node-ldapjs/issues/318#issuecomment-165769581 */
})
url
:
process
.
env
.
CLOUDRON_LDAP_URL
,
timeout
:
10000
,
/* 10 seconds */
reconnect
:
true
/* undocumented option to automatically reconnect on connection failure : https://github.com/joyent/node-ldapjs/issues/318#issuecomment-165769581 */
})
;
const
bind
=
(
dn
,
password
)
=>
new
Promise
((
resolve
,
reject
)
=>
client
.
bind
(
dn
,
password
,
err
=>
err
?
reject
(
err
)
:
resolve
())
)
client
.
bind
(
dn
,
password
,
err
=>
err
?
reject
(
err
)
:
resolve
())
)
;
const
search
=
(
username
)
=>
new
Promise
((
resolve
,
reject
)
=>
{
const
filter
=
username
?
{
filter
:
`(|(uid=
${
username
}
)(mail=
${
username
}
)(username=
${
username
}
)(sAMAccountName=
${
username
}
))`
}
:
{}
client
.
search
(
process
.
env
.
CLOUDRON_LDAP_USERS_BASE_DN
,
filter
,
(
err
,
res
)
=>
{
if
(
err
)
return
reject
(
err
)
const
filter
=
username
?
{
filter
:
`(|(uid=
${
username
}
)(mail=
${
username
}
)(username=
${
username
}
)(sAMAccountName=
${
username
}
))`
}
:
{};
client
.
search
(
process
.
env
.
CLOUDRON_LDAP_USERS_BASE_DN
,
filter
,
(
err
,
res
)
=>
{
if
(
err
)
return
reject
(
err
);
const
entries
=
[]
let
done
=
false
res
.
on
(
'
searchEntry
'
,
entry
=>
{
if
(
done
)
return
entries
.
push
(
entry
.
object
)
})
res
.
on
(
'
error
'
,
err
=>
{
if
(
done
)
return
done
=
true
reject
(
err
)
})
res
.
on
(
'
end
'
,
result
=>
{
if
(
done
)
return
done
=
true
if
(
result
.
status
===
0
)
{
resolve
(
entries
)
}
else
{
reject
(
new
Error
(
'
Unexpected error while retrieving users from LDAP. Status:
'
+
result
.
status
))
}
})
})
})
const
entries
=
[];
let
done
=
false
;
res
.
on
(
'
searchEntry
'
,
entry
=>
{
if
(
done
)
return
;
entries
.
push
(
entry
.
object
);
});
res
.
on
(
'
error
'
,
err
=>
{
if
(
done
)
return
;
done
=
true
;
reject
(
err
);
});
res
.
on
(
'
end
'
,
result
=>
{
if
(
done
)
return
;
done
=
true
;
if
(
result
.
status
===
0
)
{
resolve
(
entries
);
}
else
{
reject
(
new
Error
(
'
Unexpected error while retrieving users from LDAP. Status:
'
+
result
.
status
));
}
});
});
})
;
const
auth
=
(
username
,
password
)
=>
search
(
username
)
.
then
(
entries
=>
{
if
(
entries
.
length
!==
1
)
{
throw
new
Error
(
'
Unknown user
'
)
}
else
{
return
bind
(
`cn=
${
entries
[
0
].
username
}
,
${
process
.
env
.
CLOUDRON_LDAP_USERS_BASE_DN
}
`
,
password
)
.
then
(()
=>
({
username
:
entries
[
0
].
username
,
displayName
:
entries
[
0
].
displayname
,
email
:
entries
[
0
].
email
}))
.
catch
(()
=>
{
throw
new
Error
(
'
Wrong password
'
)
})
}
})
.
then
(
entries
=>
{
if
(
entries
.
length
!==
1
)
{
throw
new
Error
(
'
Unknown user
'
);
}
else
{
return
bind
(
`cn=
${
entries
[
0
].
username
}
,
${
process
.
env
.
CLOUDRON_LDAP_USERS_BASE_DN
}
`
,
password
)
.
then
(()
=>
({
username
:
entries
[
0
].
username
,
displayName
:
entries
[
0
].
displayname
,
email
:
entries
[
0
].
email
}))
.
catch
(()
=>
{
throw
new
Error
(
'
Wrong password
'
);
});
}
});
const
cache
=
{
data
:
null
,
duration
:
/* 1 min: */
60
/* seconds */
*
1000
/* milliseconds */
,
// User can change this value to modify duration of caching or disable with 0
time
:
Date
.
now
()
}
data
:
null
,
duration
:
/* 1 min: */
60
/* seconds */
*
1000
/* milliseconds */
,
// User can change this value to modify duration of caching or disable with 0
time
:
Date
.
now
()
}
;
const
listUsers
=
(
useCache
=
true
)
=>
{
if
(
useCache
&&
cache
.
data
&&
Date
.
now
()
-
cache
.
time
<
cache
.
duration
)
return
Promise
.
resolve
(
cache
.
data
)
return
search
()
.
then
(
entries
=>
{
cache
.
time
=
Date
.
now
()
// remember the cache
cache
.
data
=
entries
return
entries
})
}
if
(
useCache
&&
cache
.
data
&&
Date
.
now
()
-
cache
.
time
<
cache
.
duration
)
return
Promise
.
resolve
(
cache
.
data
);
return
search
()
.
then
(
entries
=>
{
cache
.
time
=
Date
.
now
();
// remember the cache
cache
.
data
=
entries
;
return
entries
;
});
}
;
const
doesUserExist
=
(
username
,
useCache
=
true
)
=>
listUsers
(
useCache
)
.
then
(
users
=>
users
.
some
(
user
=>
user
.
username
===
username
))
.
then
(
users
=>
users
.
some
(
user
=>
user
.
username
===
username
));
module
.
exports
=
{
auth
,
doesUserExist
}
auth
,
doesUserExist
}
;
src/openvpn.js
View file @
0cd54219
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment