-
-
Notifications
You must be signed in to change notification settings - Fork 20
/
server.ts
91 lines (77 loc) · 2.89 KB
/
server.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
import * as fs from 'fs';
import * as bodyParser from 'body-parser';
import { getUser, createToken, verifyToken } from './services/auth';
import { assignEntity } from './middleware';
import { Constants } from 'samlify';
export default function server(app) {
app.use(bodyParser.urlencoded({ extended: false }));
// for pretty print debugging
app.set('json spaces', 2);
// assign the session sp and idp based on the params
app.use(assignEntity);
// assertion consumer service endpoint (post-binding)
app.post('/sp/acs', async (req, res) => {
try {
const { extract } = await req.sp.parseLoginResponse(req.idp, 'post', req);
const { login } = extract.attributes;
// get your system user
const payload = getUser(login);
// assign req user
req.user = { nameId: login };
if (payload) {
// create session and redirect to the session page
const token = createToken(payload);
return res.redirect(`/?auth_token=${token}`);
}
throw new Error('ERR_USER_NOT_FOUND');
} catch (e) {
console.error('[FATAL] when parsing login response sent from okta', e);
return res.redirect('/');
}
});
// call to init a sso login with redirect binding
app.get('/sso/redirect', async (req, res) => {
const { id, context: redirectUrl } = await req.sp.createLoginRequest(req.idp, 'redirect');
return res.redirect(redirectUrl);
});
app.get('/sso/post', async (req, res) => {
const { id, context } = await req.sp.createLoginRequest(req.idp, 'post');
// construct form data
const endpoint = req.idp.entityMeta.getSingleSignOnService('post') as string;
const requestForm = fs
.readFileSync('./request.html')
.toString()
.replace('$ENDPOINT', endpoint)
.replace('$CONTEXT', context);
return res.send(requestForm);
});
// endpoint where consuming logout response
app.post('/sp/sso/logout', async (req, res) => {
const { extract } = await req.sp.parseLogoutResponse(req.idp, 'post', req);
return res.redirect('/logout');
});
app.get('/sp/single_logout/redirect', async (req, res) => {
const { context: redirectUrl } = await req.sp.createLogoutRequest(req.idp, 'redirect', { logoutNameID: '[email protected]' });
return res.redirect(redirectUrl);
});
// distribute the metadata
app.get('/sp/metadata', (req, res) => {
res.header('Content-Type', 'text/xml').send(req.sp.getMetadata());
});
app.get('/idp/metadata', (req, res) => {
res.header('Content-Type', 'text/xml').send(req.idp.getMetadata());
});
// get user profile
app.get('/profile', (req, res) => {
try {
const bearer = req.headers.authorization.replace('Bearer ', '');
const { verified, payload } = verifyToken(bearer)
if (verified) {
return res.json({ profile: payload });
}
return res.send(401);
} catch (e) {
res.send(401);
}
});
}