-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add support for App ID authentication
- Add express server implementation integrated with App ID - Add Dockerfile-express that builds container image using express server and create Dockerfile soft link to -express file - Fix nginx proxy config (need to configure App ID integration) closes #72 Signed-off-by: Sean Sundberg <[email protected]>
- Loading branch information
Showing
18 changed files
with
3,370 additions
and
50 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Dockerfile-express |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
FROM registry.access.redhat.com/ubi9/nodejs-18:1-70.1695740477 | ||
|
||
WORKDIR /opt/app-root/src | ||
|
||
COPY --chown=default:root . . | ||
|
||
RUN mkdir -p /opt/app-root/src/node_modules && \ | ||
ls -lA && \ | ||
npm ci | ||
|
||
EXPOSE 5173 | ||
|
||
CMD ["npm", "run", "dev", "--", "--host"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
FROM registry.access.redhat.com/ubi9/nodejs-18:1-70.1695740477 AS builder | ||
|
||
WORKDIR /opt/app-root/src | ||
|
||
COPY --chown=default:root . . | ||
|
||
RUN mkdir -p /opt/app-root/src/node_modules && \ | ||
ls -lA && \ | ||
npm ci && \ | ||
npm run build | ||
|
||
FROM registry.access.redhat.com/ubi9/nodejs-18:1-70.1695740477 | ||
|
||
WORKDIR /opt/app-root/src | ||
|
||
COPY --from=builder --chown=default:root /opt/app-root/src/dist ./dist | ||
|
||
WORKDIR /opt/app-root/src/server | ||
|
||
COPY --chown=default:root ./server/* . | ||
|
||
RUN npm ci | ||
|
||
EXPOSE 8080 | ||
|
||
CMD ["npm", "start", "--", "--host"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
location / { | ||
try_files $uri /index.html; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,182 @@ | ||
|
||
const express = require('express'); | ||
const session = require('express-session'); | ||
const proxy = require('express-http-proxy'); | ||
const url = require('url'); | ||
const path = require('path'); | ||
const passport = require('passport'); | ||
const WebAppStrategy = require("ibmcloud-appid").WebAppStrategy; | ||
|
||
const CALLBACK_URL = "/ibm/cloud/appid/callback"; | ||
const LOGOUT_URL = "/ibm/cloud/appid/logout"; | ||
const LOGOUT2_URL = "/logout"; | ||
const LOGIN_URL = "/ibm/cloud/appid/login"; | ||
const LOGIN2_URL = "/login"; | ||
const LANDING_PAGE_URL = "/"; | ||
const CHANGE_PASSWORD_URL = "/ibm/cloud/appid/change_password"; | ||
const CHANGE_PASSWORD2_URL = "/change_password"; | ||
const FORGOT_PASSWORD_URL = "/ibm/cloud/appid/forgot_password"; | ||
const FORGOT_PASSWORD2_URL = "/forgot_password"; | ||
|
||
const BACKEND_HOST = process.env.BACKEND_HOST || 'localhost:3000' | ||
const PORT = process.env.PORT || '8080' | ||
const HOST = process.env.HOST || 'http://localhost:8080' | ||
|
||
const COOKIE_NAME = 'refreshToken' | ||
|
||
const createServer = () => { | ||
const app = express(); | ||
app.use(session({ | ||
secret: "654321", | ||
resave: true, | ||
saveUninitialized: true | ||
})); | ||
app.use(passport.initialize()); | ||
app.use(passport.session()); | ||
|
||
const webAppStrategy = new WebAppStrategy({ | ||
clientId: "59ce4a7b-a417-461b-a491-14c647e22b6f", | ||
tenantId: "cefd8632-e25b-4b75-9077-a8b6952d39f4", | ||
secret: '', | ||
oAuthServerUrl: "https://us-south.appid.cloud.ibm.com/oauth/v4/cefd8632-e25b-4b75-9077-a8b6952d39f4", | ||
redirectUri: `${HOST}${CALLBACK_URL}`, | ||
}) | ||
|
||
passport.use(webAppStrategy); | ||
|
||
passport.serializeUser((user, cb) => { | ||
cb(null, user); | ||
}); | ||
passport.deserializeUser((obj, cb) => { | ||
cb(null, obj); | ||
}); | ||
|
||
app.get(CALLBACK_URL, passport.authenticate(WebAppStrategy.STRATEGY_NAME, { keepSessionInfo: true })); | ||
|
||
app.get(LOGIN_URL, passport.authenticate(WebAppStrategy.STRATEGY_NAME, { | ||
successRedirect: LANDING_PAGE_URL, | ||
forceLogin: true | ||
})); | ||
app.get(LOGIN2_URL, passport.authenticate(WebAppStrategy.STRATEGY_NAME, { | ||
successRedirect: LANDING_PAGE_URL, | ||
forceLogin: true | ||
})); | ||
|
||
app.get(FORGOT_PASSWORD_URL, passport.authenticate(WebAppStrategy.STRATEGY_NAME, { | ||
successRedirect: LANDING_PAGE_URL, | ||
show: WebAppStrategy.FORGOT_PASSWORD | ||
})); | ||
app.get(FORGOT_PASSWORD2_URL, passport.authenticate(WebAppStrategy.STRATEGY_NAME, { | ||
successRedirect: LANDING_PAGE_URL, | ||
show: WebAppStrategy.FORGOT_PASSWORD | ||
})); | ||
|
||
app.get(CHANGE_PASSWORD_URL, passport.authenticate(WebAppStrategy.STRATEGY_NAME, { | ||
successRedirect: LANDING_PAGE_URL, | ||
show: WebAppStrategy.CHANGE_PASSWORD | ||
})); | ||
app.get(CHANGE_PASSWORD2_URL, passport.authenticate(WebAppStrategy.STRATEGY_NAME, { | ||
successRedirect: LANDING_PAGE_URL, | ||
show: WebAppStrategy.CHANGE_PASSWORD | ||
})); | ||
|
||
const logout = (req, res) => { | ||
console.log('Logging out') | ||
req._sessionManager = false; | ||
WebAppStrategy.logout(req); | ||
req.logout(); | ||
req.session = null; | ||
res.clearCookie(COOKIE_NAME); | ||
res.redirect(LANDING_PAGE_URL); | ||
} | ||
app.get(LOGOUT_URL, logout); | ||
app.get(LOGOUT2_URL, logout); | ||
|
||
const apiProxy = proxy(BACKEND_HOST, { | ||
proxyReqPathResolver: req => url.parse(req.baseUrl).path | ||
}); | ||
app.use('/api/*', apiProxy); | ||
|
||
const graphqlProxy = proxy(`${BACKEND_HOST}/graphql`, { | ||
proxyReqPathResolver: req => url.parse(req.baseUrl).path | ||
}); | ||
app.use('/graphql/*', graphqlProxy); | ||
app.use('/graphql', graphqlProxy); | ||
|
||
const subscriptionProxy = proxy(`${BACKEND_HOST}/subscription`, { | ||
proxyReqPathResolver: req => url.parse(req.baseUrl).path | ||
}); | ||
app.use('/subscription/*', subscriptionProxy); | ||
app.use('/subscription', subscriptionProxy); | ||
|
||
function storeRefreshTokenInCookie(req, res, next) { | ||
const refreshToken = req.session[WebAppStrategy.AUTH_CONTEXT][COOKIE_NAME]; | ||
console.log('Storing refresh token: ', {refreshToken}) | ||
if (refreshToken) { | ||
/* An example of storing user's refresh-token in a cookie with expiration of a month */ | ||
res.cookie(COOKIE_NAME, refreshToken, { | ||
maxAge: 1000 * 60 * 60 * 24 * 30 /* 30 days */ | ||
}); | ||
} | ||
next(); | ||
} | ||
|
||
function isLoggedIn(req) { | ||
const result = req.session[WebAppStrategy.AUTH_CONTEXT]; | ||
|
||
console.log('isLoggedIn? ', result) | ||
|
||
return result; | ||
} | ||
|
||
function tryToRefreshTokenIfNotLoggedIn(req, res, next) { | ||
if (isLoggedIn(req)) { | ||
return next(); | ||
} | ||
|
||
const refreshToken = (req.cookies || {})[COOKIE_NAME] | ||
if (!refreshToken) { | ||
return next(); | ||
} | ||
|
||
console.log('Refreshing tokens') | ||
webAppStrategy.refreshTokens(req, refreshToken).then(function () { | ||
console.log('Next') | ||
next(); | ||
}).catch(err => console.error('Error refreshing tokens: ', {err})); | ||
} | ||
|
||
app.get( | ||
"/secure/*", | ||
tryToRefreshTokenIfNotLoggedIn, | ||
passport.authenticate(WebAppStrategy.STRATEGY_NAME, { keepSessionInfo: true }), | ||
storeRefreshTokenInCookie, | ||
(req, res) => { | ||
res.sendFile(path.resolve(__dirname, '..', 'dist', 'index.html')) | ||
} | ||
); | ||
|
||
// | ||
// app.get( | ||
// "/secure/*", | ||
// passport.authenticate(WebAppStrategy.STRATEGY_NAME), | ||
// (req, res) => { | ||
// res.sendFile(path.resolve(__dirname, '..', 'dist', 'index.html')) | ||
// } | ||
// ); | ||
|
||
// app.get('*', passport.authenticate(WebAppStrategy.STRATEGY_NAME), (req, res) => { | ||
// res.sendFile(path.resolve(__dirname, '..', 'dist', 'index.html')) | ||
// }) | ||
// app.get('*', (req, res) => { | ||
// res.sendFile(path.resolve(__dirname, '..', 'dist', 'index.html')) | ||
// }) | ||
app.use(express.static(path.join(__dirname, '..', 'dist'))) | ||
|
||
|
||
return app; | ||
} | ||
|
||
createServer().listen(PORT, () => { | ||
console.log(`Server started on port ${PORT}`) | ||
}) |
Oops, something went wrong.