-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathapp.js
146 lines (113 loc) · 3.76 KB
/
app.js
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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
import express from 'express'
import exphbs from 'express-handlebars'
import compression from 'compression'
import createError from 'http-errors'
import {URL} from 'url'
import moment from 'moment'
import cookieParser from 'cookie-parser'
import logger from 'morgan'
import debug from 'debug'
import jwt from 'jsonwebtoken'
import dotenv from 'dotenv'
import axios from 'axios'
import axiosThrottle from 'axios-request-throttle'
import indexRouter from './server/routes/index.js'
import registrationRouter from './server/routes/registration.js'
const dbg = debug('SRA:app')
const errs = debug('SRA:errors')
dotenv.config()
const {ZM_KEY, ZM_SECRET} = process.env
/**
* Generates a JWT token for the Zoom API
* @see https://github.com/zoom/zoom-api-jwt
* @see https://github.com/brandonabajelo-zoom/jwt-gen/
* @see https://marketplace.zoom.us/docs/guides/build/jwt-app/
* @param exp - seconds until the token expires
* @return {string} a JWT token
*/
function generateJWT(exp = 5) {
if (typeof exp !== 'number' || exp <= 0)
throw createError(500, 'generateJWT(): exp parameter expected to be a number greater than 0')
return jwt.sign({iss: ZM_KEY}, ZM_SECRET, {expiresIn: exp})
}
/**
* Adds the provided jwt to axios auth header
* @param {string} token - JWT that will be set in the header
*/
function setAuthHeader(token) {
axios.defaults.headers.common.Authorization = `Bearer ${token}`
}
/* App Config */
const app = express()
axios.defaults.baseURL = 'https://api.zoom.us/v2'
// log Axios requests and responses
const logFunc = (r) => {
if (process.env.NODE_ENV !== 'production') {
const { method, status, url, baseURL, config } = r;
const endp = url || config?.url;
const base = baseURL || config?.baseURL;
let str = new URL(endp, base).href;
if (method) str = `${method.toUpperCase()} ${str}`;
if (status) str = `${status} ${str}`;
debug(`SRA:axios`)(str);
}
return r;
};
axios.interceptors.request.use(logFunc);
axios.interceptors.response.use(logFunc);
// throttle requests to the Zoom API so they fit within the light rate limits
axiosThrottle.use(axios, {requestsPerSecond: 30})
app.locals.generateJWT = generateJWT
app.locals.setAuthHeader = setAuthHeader
app.locals.configureAuth = () => {
setAuthHeader(generateJWT())
}
/* View Engine Setup */
const layoutsDir = new URL('server/views', import.meta.url).pathname
const hbs = exphbs.create({
layoutsDir,
extname: '.hbs',
defaultLayout: 'layout',
helpers: {
calendar: t => moment(t).calendar(null, {
sameElse: 'LLL'
})
},
})
app.engine('.hbs', hbs.engine)
app.set('view engine', 'hbs')
app.set('views', layoutsDir);
/* Middleware */
app.use(express.json())
app.use(express.urlencoded({extended: false}))
app.use(cookieParser())
app.use(logger('dev', {stream: {write: msg => dbg(msg)}}))
app.use(compression())
app.use(express.static(new URL('public', import.meta.url).pathname))
/* Routing */
app.use('/', indexRouter)
app.use('/r', registrationRouter)
// eslint-disable-next-line no-unused-vars
app.use((err, req, res, next) => {
const status = err.status || 500
const title = `Error ${err.status}`
// set locals, only providing error in development
res.locals.message = err.message
res.locals.error = req.app.get('env') === 'development' ? err : {}
if (res.locals.error)
errs(`${title} %s`, err.stack)
// render the error page
res.status(status)
res.render('error', {
title,
cardTitle: title,
cardText: err.message,
cardClass: 'has-background-danger',
textClass: 'has-text-white',
})
})
// redirect users to the home page if they get a 404 route
app.get('*', (req, res) => {
res.redirect('/')
})
export default app