Skip to content

Commit

Permalink
chore: adding oauth2 login and consent code to main repo
Browse files Browse the repository at this point in the history
  • Loading branch information
Nicolas Burtey committed Sep 14, 2023
1 parent 7423e5d commit bcdb6f7
Show file tree
Hide file tree
Showing 24 changed files with 3,231 additions and 0 deletions.
1 change: 1 addition & 0 deletions frontend/login-consent/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.env
5 changes: 5 additions & 0 deletions frontend/login-consent/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.bin/
node_modules/
.bin/
.idea
lib/
1 change: 1 addition & 0 deletions frontend/login-consent/.prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

3 changes: 3 additions & 0 deletions frontend/login-consent/.reference-ignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
**/node_modules
docs
CHANGELOG.md
20 changes: 20 additions & 0 deletions frontend/login-consent/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
FROM node:14.15-alpine3.12

RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app

RUN adduser -S ory -D -u 10000 -s /bin/nologin

COPY package.json package.json
COPY package-lock.json package-lock.json
RUN npm ci --silent

COPY . /usr/src/app

RUN npm run build

USER 10000

ENTRYPOINT npm run serve

EXPOSE 3000
44 changes: 44 additions & 0 deletions frontend/login-consent/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# login-consent-provider

This is the User Login and Consent flow for the Galoy stack over the OAuth2 service (Hydra) in NodeJS.

---

<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->

- [login-consent-provider](#login-consent-provider)
- [Overview](#overview)
- [Running](#running)
- [FAQ](#faq)
- [TLS Termination](#tls-termination)

<!-- END doctoc generated TOC please keep comment here to allow auto update -->

---

## Overview

Apart from additions (`./routes/login.ts`, `./routes/consent.ts`) and their
respective templates, only a [CSRF Middleware] has been added. Everything else
is the standard express template.

Also, a simple helper that makes HTTP requests has been added to
`./services/hydra.js` which uses the `node-fetch` library.

To set this example up with ORY Hydra, please refer to the
[official documentation](https://www.ory.sh/docs).

## Running

Please head over to the
[ORY Hydra 5 Minute Tutorial](https://www.ory.sh/docs/hydra/5min-tutorial) to
see how this works.

## FAQ

### TLS Termination

You can mock TLS Termination by setting environment variable
`MOCK_TLS_TERMINATION` to any value, for example `MOCK_TLS_TERMINATION=y`. This
will add `X-Forwarded-Proto: https` to each HTTP Request Header.
51 changes: 51 additions & 0 deletions frontend/login-consent/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
{
"name": "galoy-login-consent-logout",
"version": "0.0.1",
"bin": {
"hydra-login-consent-logout": "lib/app.js"
},
"files": [
"lib",
"views"
],
"scripts": {
"build": "tsc",
"serve": "HYDRA_ADMIN_URL=http://localhost:4445 node lib/app.js",
"start": "HYDRA_ADMIN_URL=http://localhost:4445 ts-node-dev --watch public,views --respawn src/app.ts",
"test": "npm-run-all build",
"prepublishOnly": "tsc"
},
"prettier": "ory-prettier-styles",
"dependencies": {
"@ory/hydra-client": "^2.1.1",
"@types/axios": "^0.14.0",
"@types/cookie-parser": "^1.4.2",
"@types/csurf": "^1.9.36",
"@types/express": "^4.17.7",
"@types/morgan": "^1.9.1",
"@types/url-join": "^4.0.0",
"axios": "^1.5.0",
"body-parser": "^1.19.0",
"cookie-parser": "^1.4.5",
"csurf": "^1.11.0",
"debug": "^4.1.1",
"express": "^4.17.3",
"morgan": "^1.10.0",
"node-fetch": "^2.6.7",
"pug": "^2.0.4",
"querystring": "^0.2.0",
"react": "^18.2.0",
"serve-favicon": "^2.5.0",
"typescript": "^3.7.5",
"url-join": "^4.0.1"
},
"devDependencies": {
"@types/serve-favicon": "^2.5.4",
"license-checker": "^25.0.1",
"npm-run-all": "^4.1.5",
"ory-prettier-styles": "1.3.0",
"prettier": "^2.7.1",
"prettier-plugin-packagejson": "^2.2.18",
"ts-node-dev": "^1.0.0-pre.43"
}
}
Binary file added frontend/login-consent/public/favicon.ico
Binary file not shown.
74 changes: 74 additions & 0 deletions frontend/login-consent/src/app.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
// Copyright © 2023 Ory Corp
// SPDX-License-Identifier: Apache-2.0

import express, { NextFunction, Response, Request } from "express"
import path from "path"
import logger from "morgan"
import cookieParser from "cookie-parser"
import bodyParser from "body-parser"
import favicon from "serve-favicon"

import routes from "./routes"
import login from "./routes/login"
import logout from "./routes/logout"
import consent from "./routes/consent"

const app = express()

// view engine setup
app.set("views", path.join(__dirname, "..", "views"))
app.set("view engine", "pug")

// uncomment after placing your favicon in /public
app.use(favicon(path.join(__dirname, "../public", "favicon.ico")))
app.use(logger("dev"))
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ extended: false }))
app.use(cookieParser())
app.use(express.static(path.join(__dirname, "public")))

app.use("/", routes)
app.use("/login", login)
app.use("/logout", logout)
app.use("/consent", consent)

// catch 404 and forward to error handler
app.use((req, res, next) => {
next(new Error("Not Found"))
})

// error handlers

// development error handler
// will print stacktrace
if (app.get("env") === "development") {
app.use((err: Error, req: Request, res: Response) => {
res.status(500)
res.render("error", {
message: err.message,
error: err,
})
})
}

// production error handler
// no stacktraces leaked to user
app.use((err: Error, req: Request, res: Response) => {
res.status(500)
res.render("error", {
message: err.message,
error: {},
})
})

app.use((err: Error, req: Request, res: Response, next: NextFunction) => {
console.error(err.stack)
res.status(500).render("error", {
message: JSON.stringify(err, null, 2),
})
})

const listenOn = Number(process.env.PORT || 3000)
app.listen(listenOn, () => {
console.log(`Listening on http://0.0.0.0:${listenOn}`)
})
18 changes: 18 additions & 0 deletions frontend/login-consent/src/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Copyright © 2023 Ory Corp
// SPDX-License-Identifier: Apache-2.0

import { Configuration, OAuth2Api } from "@ory/hydra-client"

const baseOptions: any = {}

if (process.env.MOCK_TLS_TERMINATION) {
baseOptions.headers = { "X-Forwarded-Proto": "https" }
}

const configuration = new Configuration({
basePath: process.env.HYDRA_ADMIN_URL,
})

const hydraClient = new OAuth2Api(configuration)

export { hydraClient }
Loading

0 comments on commit bcdb6f7

Please sign in to comment.