Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(identity): verified merged #364

Merged
merged 71 commits into from
Mar 30, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
71 commits
Select commit Hold shift + click to select a range
f2ee042
feat: add sequelize and pg libraries
lamkeewei Jul 8, 2021
2ab35e3
feat: add sequelize migrations configuration
lamkeewei Jul 8, 2021
e8292dc
feat: add sequelize models for identity
lamkeewei Jul 8, 2021
a57cb27
feat: add database migrations to create tables
lamkeewei Jul 8, 2021
b37afa1
feat: init database connection before starting server
lamkeewei Jul 8, 2021
9081beb
refactor: capitalize enum values and change to admin or user
lamkeewei Jul 9, 2021
b398b51
fix: use correct key in db config for username
lamkeewei Jul 15, 2021
d49e453
feat: add local dev postgres through docker compose
lamkeewei Jul 15, 2021
9280a9b
refactor: remove repo_name column
lamkeewei Jul 29, 2021
31e5640
feat: add unique index on email
lamkeewei Jul 30, 2021
2fb6556
feat: add SiteService
lamkeewei Jul 29, 2021
e22a236
feat: add AuthService
lamkeewei Jul 29, 2021
7cfaf3d
feat: add middleware to inject site access token
lamkeewei Jul 29, 2021
be015c1
refactor: change variable casing of imported services
lamkeewei Jul 29, 2021
53dd4ae
feat: add scaffold for AuthService otp methods
lamkeewei Jul 30, 2021
cfe8c27
feat: add UserService
lamkeewei Jul 30, 2021
6733426
feat: extend auth middleware to check for isomer user id
lamkeewei Jul 30, 2021
d185630
feat: add routes for send and verify otp
lamkeewei Jul 30, 2021
d1c39d4
feat: implement actual totp methods
lamkeewei Jul 30, 2021
85c7c35
feat: implement check for whether otp can be sent
lamkeewei Jul 30, 2021
4d57fb9
feat: add validator for email format
lamkeewei Jul 30, 2021
689b0b0
feat: implement mail client using postman transactional api
lamkeewei Jul 30, 2021
1352e92
feat: implement TokenStore
lamkeewei Jul 31, 2021
40c4cf8
refactor: initialize services from module index
lamkeewei Jul 31, 2021
305c9d9
Merge branch 'feat/identity/site-token-middleware' into feat/identity…
lamkeewei Jul 31, 2021
38837c9
fix: use correct expiry value
lamkeewei Aug 2, 2021
98281c9
Merge branch 'develop' into feat/identity/database-models
lamkeewei Aug 23, 2021
a9f6594
feat: add github_id column to user model
lamkeewei Aug 23, 2021
4e04a88
Merge branch 'feat/identity/database-models' into feat/identity/site-…
lamkeewei Aug 23, 2021
aa0dbca
Merge branch 'feat/identity/site-token-middleware' into feat/identity…
lamkeewei Aug 23, 2021
5ed7d10
feat: allow email to be null
lamkeewei Aug 23, 2021
faba2fb
Merge branch 'feat/identity/database-models' into feat/identity/site-…
lamkeewei Aug 23, 2021
895d1c4
Merge branch 'feat/identity/site-token-middleware' into feat/identity…
lamkeewei Aug 23, 2021
ccf4a88
feat: create user with github id
lamkeewei Aug 23, 2021
d9eee2f
feat: apply verifyJwt for otp routes
lamkeewei Aug 23, 2021
5a49a54
feat: add methods for update and find by github id
lamkeewei Aug 23, 2021
9ce8f5c
feat: whitelist only by domain
lamkeewei Aug 23, 2021
617d217
feat: return email in whoami response
lamkeewei Aug 23, 2021
68802d6
feat: add verifyOtp endpoint
lamkeewei Aug 23, 2021
f86e9a3
refactor: rename to email otp methods
lamkeewei Aug 23, 2021
00df609
refactor: move otp routes to /user
lamkeewei Aug 23, 2021
0308661
refactor: move identity services to module
lamkeewei Aug 24, 2021
631ed42
Merge branch 'feat/identity/site-token-middleware' into feat/identity…
lamkeewei Aug 24, 2021
e2b7e5c
refactor: move email verification methods to user service
lamkeewei Aug 24, 2021
14f575b
feat: add verification for contact number
lamkeewei Aug 24, 2021
de336b0
feat: use bad request error
lamkeewei Aug 24, 2021
c5de8b3
Merge branch 'develop' into feat/identity/database-models
lamkeewei Nov 8, 2021
0cfc7b3
Merge branch 'feat/identity/database-models' into feat/identity/site-…
lamkeewei Nov 8, 2021
44f40ee
Merge branch 'feat/identity/site-token-middleware' into feat/identity…
lamkeewei Nov 8, 2021
43d8651
chore: upgrade sequelize
lamkeewei Nov 8, 2021
9614c63
Merge branch 'feat/identity/database-models' into feat/identity/site-…
lamkeewei Nov 8, 2021
223c398
Merge branch 'feat/identity/site-token-middleware' into feat/identity…
lamkeewei Nov 8, 2021
ac24aaf
Merge pull request #241 from isomerpages/feat/identity/email-login
lamkeewei Nov 8, 2021
55760a2
Merge pull request #240 from isomerpages/feat/identity/site-token-mid…
lamkeewei Nov 8, 2021
9e9f367
refactor: use router pattern for users routes
lamkeewei Nov 9, 2021
3bda36a
fix: undefined reference to usersService
lamkeewei Nov 9, 2021
3cda458
chore: add sms cred name to example env file
lamkeewei Nov 9, 2021
c4b7ef0
feat: track last logged in date time
lamkeewei Nov 22, 2021
25ff573
Merge branch 'develop' into feat/identity/verified-contact-details
lamkeewei Nov 22, 2021
3fb07db
feat: update err message for non-govt emails
lamkeewei Nov 22, 2021
29b81e3
Merge branch 'develop' into feat/identity/verified-contact-details
seaerchin Feb 24, 2022
ae05aa9
build(pcakage-lock): update build deps
seaerchin Feb 28, 2022
aec194e
feat(identity): add types (#367)
seaerchin Mar 17, 2022
8a4057b
test(identity): integration tests for user routes (#382)
seaerchin Mar 23, 2022
40cffa8
Refactor/move identity to v2 endpoints (#368)
alexanderleegs Mar 28, 2022
460f6e8
Merge branch 'develop' into feat/identity/verified-merged
alexanderleegs Mar 28, 2022
db90953
Fix: merge errors
alexanderleegs Mar 28, 2022
ec16fa8
Fix: modify sequelizerc file to use config.js (#406)
alexanderleegs Mar 30, 2022
ed1ca83
feat(identity): infrastructure changes (#405)
seaerchin Mar 30, 2022
e6873bd
Fix: set reply_to param for OTP email (#408)
alexanderleegs Mar 30, 2022
b96bbb0
Fix: ping endpoint order (#407)
alexanderleegs Mar 30, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 17 additions & 4 deletions .env-example
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,6 @@ export GITHUB_ORG_NAME="isomerpages"
export GITHUB_BUILD_ORG_NAME="opengovsg"
export GITHUB_BUILD_REPO_NAME="isomer-build"
export MUTEX_TABLE_NAME=""
export E2E_TEST_REPO="e2e-test-repo"
export E2E_TEST_SECRET="blahblahblah"
export E2E_TEST_GH_TOKEN=""

# Required to connect to DynamoDB
export AWS_ACCESS_KEY_ID=""
Expand All @@ -22,4 +19,20 @@ export AWS_SECRET_ACCESS_KEY=""
# Required to run end-to-end tests
export E2E_TEST_REPO="e2e-test-repo"
export E2E_TEST_SECRET=""
export E2E_TEST_GH_TOKEN=""
export E2E_TEST_GH_TOKEN=""

# Database
export DB_URI="postgres://isomer:password@localhost:15432/isomercms_dev"
export DB_MIN_POOL="1"
export DB_MAX_POOL="10"
export DB_ENABLE_LOGGING=""

export LOCAL_SITE_ACCESS_TOKEN=""
export OTP_SECRET="dummysecret"
export DOMAIN_WHITELIST=".gov.sg"

# Email
export POSTMAN_API_KEY=""

# SMS
export POSTMAN_SMS_CRED_NAME=""
28 changes: 28 additions & 0 deletions .env.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
export CLIENT_ID="i am a client"
export CLIENT_SECRET="i am a secret"
export REDIRECT_URI="http://localhost:8081/v1/auth"
export NODE_ENV="test"
export COOKIE_DOMAIN="localhost"
export AUTH_TOKEN_EXPIRY_DURATION_IN_MILLISECONDS=800000000
export JWT_SECRET="blah"
export ENCRYPTION_SECRET="blah"
export FRONTEND_URL="http://localhost:3000"
export GITHUB_ORG_NAME="isomerpages"
export GITHUB_BUILD_ORG_NAME="opengovsg"
export GITHUB_BUILD_REPO_NAME="isomer-build"

# Database
export DB_URI="postgres://isomer:password@localhost:54321/isomercms_test"
export DB_MIN_POOL="1"
export DB_MAX_POOL="10"
export DB_ENABLE_LOGGING=""

export LOCAL_SITE_ACCESS_TOKEN=""
export OTP_SECRET="dummysecret"
export DOMAIN_WHITELIST=".gov.sg"

# Email
export POSTMAN_API_KEY="some api key"

# SMS
export POSTMAN_SMS_CRED_NAME="isomer"
41 changes: 32 additions & 9 deletions .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,18 @@
},
"extends": [
"airbnb-base",
"prettier"
"prettier",
"plugin:import/typescript"
],
"plugins": ["only-warn", "import"],
"parserOptions": {
"ecmaVersion": 12
},
"rules": {
"no-underscore-dangle": "off",
"class-methods-use-this": "off",
"import/no-unresolved": "error",
"import/extensions": ["warn", "never"],
"import/order": [
"error",
{
Expand All @@ -24,8 +28,7 @@
},
"newlines-between": "always",
"groups": ["builtin", "external", "internal", "parent", "sibling", "index", "object"],
"pathGroups": [
{
"pathGroups": [{
"pattern": "@logger/**",
"group": "internal",
"position": "before"
Expand Down Expand Up @@ -56,31 +59,51 @@
"position": "before"
},
{
"pattern": "@validators/**",
"group": "internal",
"position": "before"
"pattern": "@validators/**",
"group": "internal",
"position": "before"
}
]
}
]
},
"overrides": [
{
"files": ["*.ts", "*.tsx"],
"parser": "@typescript-eslint/parser",
"extends": ["plugin:@typescript-eslint/recommended"]
}
],
"settings": {
"import/parsers": {
"@typescript-eslint/parser": [".ts", ".tsx"]
},
"import/resolver": {
"alias": [
"typescript": {
// always try to resolve types under `<root>@types` directory even it doesn't contain any source code, like `@types/unist`
"alwaysTryTypes": true
},
"node": {
"extensions": [".js", ".jsx", ".ts", ".tsx"]
},
"alias": [
["@root", "./"],
["@classes", "./classes"],
["@errors", "./errors"],
["@logger", "./logger"],
["@middleware", "./middleware"],
["@routes", "./routes"],
["@utils", "./utils"],
["@loaders", "./loaders"],
["@database", "./database"],
["@services", "./services"],
["@validators", "./validators"],
["@fixtures", "./fixtures"]
["@fixtures", "./fixtures"],
["@database", "./database"]
]
}
},
"globals": {
"Base64": true
}
}
}
2 changes: 2 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ jobs:
${{ runner.OS }}-
- name: Install NPM
run: npm ci
- name: Build application
run: npm run build
- name: Zip application
run: zip -r "deploy.zip" * .platform -x .env-example .gitignore package-lock.json
- name: Get timestamp
Expand Down
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
.env
node_modules/
.vscode/
.vscode/
build/
8 changes: 8 additions & 0 deletions .sequelizerc
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
const path = require("path")

module.exports = {
config: path.resolve("./database", "config.js"),
"models-path": path.resolve("./database", "models"),
"seeders-path": path.resolve("./database", "seeders"),
"migrations-path": path.resolve("./database", "migrations"),
}
15 changes: 15 additions & 0 deletions __mocks__/@aws-sdk/client-secrets-manager.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// This is a manual module mock for the AWS client.
// This is done to prevent our internal services from pinging the actual AWS ones
// and to ensure our tests are 1. consistent 2. reliable.

export const mockSend = jest.fn()

export const secretsManagerClient = {
send: mockSend,
}

export const SecretsManagerClient: jest.Mock<
typeof secretsManagerClient
> = jest.fn().mockImplementation(() => secretsManagerClient)

export const GetSecretValueCommand = jest.fn((secret) => ({ SecretId: secret }))
3 changes: 3 additions & 0 deletions __mocks__/axios.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import mockAxios from "jest-mock-axios"

export default mockAxios
6 changes: 6 additions & 0 deletions __mocks__/otplib.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// eslint-disable-next-line import/prefer-default-export
export const totp = {
clone: jest.fn().mockReturnThis(),
generate: jest.fn(),
verify: jest.fn(),
}
94 changes: 0 additions & 94 deletions bin/www

This file was deleted.

91 changes: 91 additions & 0 deletions bin/www.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
#!/usr/bin/env node

/**
* Module dependencies.
*/
require("module-alias/register")

const http = require("http")

const app = require("@root/server")

const debug = require("debug")("isomercms:server")

// Import logger
const logger = require("@logger/logger")

/**
* Normalize a port into a number, string, or false.
*/

function normalizePort(val) {
const port = parseInt(val, 10)

if (isNaN(port)) {
// named pipe
return val
}

if (port >= 0) {
// port number
return port
}

return false
}

/**
* Event listener for HTTP server "error" event.
*/

function onError(error) {
if (error.syscall !== "listen") {
throw error
}

const bind = typeof port === "string" ? `Pipe ${port}` : `Port ${port}`

// handle specific listen errors with friendly messages
switch (error.code) {
case "EACCES":
logger.error(`${bind} requires elevated privileges`)
process.exit(1)
case "EADDRINUSE":
logger.error(`${bind} is already in use`)
process.exit(1)
default:
throw error
}
}

/**
* Event listener for HTTP server "listening" event.
*/

function onListening() {
const addr = server.address()
const bind = typeof addr === "string" ? `pipe ${addr}` : `port ${addr.port}`
debug(`Listening on ${bind}`)
logger.info(`isomerCMS app listening on port ${port}`)
}

/**
* Get port from environment and store in Express.
*/

const port = normalizePort(process.env.PORT || "8081")
app.set("port", port)

/**
* Create HTTP server.
*/

const server = http.createServer(app)

/**
* Listen on provided port, on all network interfaces.
*/

server.listen(port)
server.on("error", onError)
server.on("listening", onListening)
Loading