Skip to content
Merged

Dev #124

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
484f076
rate limit back to testing
ahjyrkia Jan 29, 2025
222d5ba
Merge pull request #115 from HSLdevcom/rate-limit
ahjyrkia Jan 29, 2025
27733bb
add codeql
ahjyrkia Apr 22, 2025
c025b8c
Merge pull request #116 from HSLdevcom/codeql
ahjyrkia Apr 22, 2025
a63c0f8
fix cancellation id type
ahjyrkia May 19, 2025
227bdb3
Merge pull request #117 from HSLdevcom/fix-cancellation-id
ahjyrkia May 19, 2025
f118e2e
bumped some versions
ahjyrkia May 22, 2025
eac981e
Merge pull request #118 from HSLdevcom/dependencies-update
ahjyrkia May 22, 2025
5d7f0d0
apc bike class added
ahjyrkia Jul 14, 2025
ae3adce
Merge pull request #119 from HSLdevcom/apc-bike-class
ahjyrkia Jul 15, 2025
6941b53
support for rest of the apc classes
ahjyrkia Jul 15, 2025
41c862f
Merge pull request #120 from HSLdevcom/apc-classes
ahjyrkia Jul 15, 2025
b2f6957
error response added
ahjyrkia Aug 4, 2025
cc67fbe
node bump
ahjyrkia Aug 27, 2025
b13c82f
Merge pull request #121 from HSLdevcom/48533-speed-search-error-handling
ahjyrkia Aug 27, 2025
e17e549
feat(65318): add & configure prettier autoformatter
bogdandina Sep 9, 2025
4c63aaf
feat(65318): fix sec vulnerability
bogdandina Sep 9, 2025
81252ff
feat(65318): add ci-cd github actions stage
bogdandina Sep 10, 2025
22b1dfc
feat(65318): add ci-cd github actions stage
bogdandina Sep 10, 2025
0d01ca6
Merge pull request #123 from HSLdevcom/feature/65318_use-autoformatti…
bogdandina Sep 11, 2025
2ef8e77
form data bump
ahjyrkia Oct 20, 2025
444a9be
sha.js resolution, yarn.lock
ahjyrkia Oct 20, 2025
a4760bf
dependency scan fail threshold set to critical
ahjyrkia Oct 20, 2025
770c245
validation and operators updates
ahjyrkia Oct 21, 2025
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
27 changes: 27 additions & 0 deletions .github/workflows/ci-cd.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
---
name: "CI/CD: Continuous integration and continuous deployment"
on: [pull_request]
permissions:
contents: read

jobs:
build-check:
name: 'Build & check format'
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Install Node
uses: actions/setup-node@v4
with:
node-version: "lts/*"
cache: "npm"

- name: Install NPM dependencies
run: yarn install --frozen-lockfile

- name: Check code formatting
run: npm run format:check


37 changes: 37 additions & 0 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
name: "Code analysis"
on:
push:
branches: [ "production" ]
pull_request:
branches: [ "production" ]
schedule:
- cron: '0 8 * * *'
jobs:
analyze:
name: Analyze code
runs-on: 'ubuntu-latest'
permissions:
security-events: write
packages: read
actions: read
contents: read
strategy:
fail-fast: false
matrix:
include:
- language: actions
build-mode: none
- language: JavaScript
build-mode: none
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
build-mode: ${{ matrix.build-mode }}
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
with:
category: "/language:${{matrix.language}}"
14 changes: 14 additions & 0 deletions .github/workflows/dependency-scan.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
name: 'Dependency scan'
on: [pull_request]
permissions:
contents: read
jobs:
dependency-review:
runs-on: ubuntu-latest
steps:
- name: 'Checkout Repository'
uses: actions/checkout@v4
- name: 'Dependency Review'
uses: actions/dependency-review-action@v4
with:
fail-on-severity: critical
4 changes: 4 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
node_modules
dist
build
coverage
2 changes: 1 addition & 1 deletion .prettierrc
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@
"bracketSpacing": true,
"trailingComma": "es5",
"tabWidth": 2
}
}
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM node:12-alpine
FROM node:14-alpine

RUN apk --no-cache add curl

Expand Down
19 changes: 15 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
"codestyle": "prettier \"src/**/*.{ts,js,json}\" --write",
"test": "node scripts/test.js",
"test:ci": "CI=true node scripts/test.js",
"test:staged": "CI=true node scripts/test.js --bail --findRelatedTests"
"test:staged": "CI=true node scripts/test.js --bail --findRelatedTests",
"format": "prettier --write \"src/**/*.{ts,tsx,js,jsx,json,css,md}\"",
"format:check": "prettier --check \"src/**/*.{ts,tsx,js,jsx,json,css,md}\""
},
"lint-staged": {
"*.{ts,js}": [
Expand Down Expand Up @@ -54,6 +56,7 @@
"date-fns": "^1.30.1",
"dotenv": "^6.2.0",
"express": "^4.17.1",
"express-rate-limit": "5.5.1",
"express-react-views": "^0.11.0",
"express-session": "^1.17.2",
"forever": "^0.15.3",
Expand All @@ -79,7 +82,7 @@
"uuid": "^7.0.3"
},
"devDependencies": {
"@graphql-codegen/cli": "1.8.3",
"@graphql-codegen/cli": "^1.21.8",
"@graphql-codegen/import-types-preset": "1.8.3",
"@graphql-codegen/typescript": "1.8.3",
"@graphql-codegen/typescript-resolvers": "1.8.3",
Expand All @@ -95,13 +98,21 @@
"jest": "^24.3.1",
"jest-haste-map": "^24.5.0",
"jest-resolve": "^24.5.0",
"lint-staged": "^8.1.5",
"lint-staged": "^9.0.0",
"nodemon": "^1.18.10",
"prettier": "^2.3.0",
"prettier": "^2.8.8",
"ts-jest": "^24.1.0",
"ts-node-dev": "^1.1.6",
"tslint": "^6.1.3",
"tslint-config-prettier": "^1.18.0",
"tslint-plugin-prettier": "^2.0.1"
},
"resolutions": {
"underscore": "^1.12.1",
"minimist": "^1.2.6",
"json-schema": "^0.4.0",
"@babel/traverse": "^7.23.2",
"form-data": "^4.0.4",
"sha.js": "^2.4.12"
}
}
11 changes: 10 additions & 1 deletion src/auth/groupAssignments.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import validator from 'validator'
import {
IUserInfo,
requestGroups,
Expand All @@ -13,6 +14,10 @@ export async function assignUserToGroups(userInfo: IUserInfo): Promise<IUserInfo
return userInfo
}

if (!validator.isEmail(userInfo.email)) {
return userInfo
}

const settings = await getSettings()
const domainGroups = settings.domain_groups
const autoDomainGroups = settings.auto_domain_groups
Expand All @@ -31,7 +36,11 @@ export async function assignUserToGroups(userInfo: IUserInfo): Promise<IUserInfo
)

const sessionGroups = userInfo.groups
const emailDomainGroups = assignGroups.filter((dg) => userInfo.email.endsWith(dg.domain))
const parsedDomains = userInfo.email.split('@')
const emailDomain = parsedDomains[parsedDomains.length - 1]?.toLowerCase()
const emailDomainGroups = assignGroups.filter(
(dg) => emailDomain === dg.domain.toLowerCase()
)
const groupAssignments = uniq(flatten(emailDomainGroups.map(({ groups }) => groups)))
const assignToGroups = difference(groupAssignments, sessionGroups)

Expand Down
1 change: 1 addition & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { mapValues, orderBy } from 'lodash'
import fs from 'fs-extra'
import 'dotenv/config'

const SECRETS_PATH = '/run/secrets/'

Expand Down
9 changes: 4 additions & 5 deletions src/creators/createAreaJourneysResponse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
} from '../types/generated/schema-types'
import { CachedFetcher } from '../types/CachedFetcher'
import { cacheFetch } from '../cache'
import { ForbiddenError } from 'apollo-server-errors'
import { groupBy, map } from 'lodash'
import { createAreaJourneyObject } from '../objects/createAreaJourneyObject'
import { createBBoxString } from '../utils/createBBoxString'
Expand Down Expand Up @@ -47,7 +48,9 @@ export const createAreaJourneysResponse = async (
(events: Vehicles[]) => createAreaJourneyObject(events)
)
}

if (speedFilter && !user) {
throw new ForbiddenError('Authentication required. Please login.')
}
// Cache for when a link containing an area query is shared.
const cacheKey = `area_journeys_${createBBoxString(bbox)}_${minTime}_${maxTime}_${date}_${
!!user && unsignedEvents ? 'unsigned' : ''
Expand All @@ -58,10 +61,6 @@ export const createAreaJourneysResponse = async (
return []
}

if (speedFilter && !user) {
return []
}

let hslGroup: boolean = false
if (user) {
if (requireUser(user, 'HSL')) {
Expand Down
2 changes: 1 addition & 1 deletion src/datasources/HFPDataSource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ ORDER BY tst DESC;
): Promise<Vehicles[]> {
const { minLat, maxLat, minLng, maxLng } = bbox
const speedInMetersPerSecond = speedFilter / 3.6

maxTime = maxTime.clone().add(4, 'hours')
const createQuery = (table) => {
return this.db.raw(
`
Expand Down
2 changes: 1 addition & 1 deletion src/objects/createCancellation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export function createCancellation(cancellation: DBCancellation): Cancellation {
const cancellationData: CancellationDataType | null = cancellation.data || null

return {
id: cancellation.id,
id: cancellation.id.toString(),
routeId: cancellation.route_id,
direction: getDirection(cancellation.direction_id),
departureDate: cancellation.start_date,
Expand Down
17 changes: 17 additions & 0 deletions src/objects/createJourneyEventObject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,15 @@ export function createPassengerCountEventObject(
const vehicleLoad = authorized ? event.vehicle_load : null
const totalPassengersIn = authorized ? event.total_passengers_in : null
const totalPassengersOut = authorized ? event.total_passengers_out : null
const bikesIn = authorized ? event.bikes_in : null
const bikesOut = authorized ? event.bikes_out : null

const wheelchairsIn = authorized ? event.wheelchairs_in : null
const wheelchairsOut = authorized ? event.wheelchairs_out : null
const pramsIn = authorized ? event.prams_in : null
const pramsOut = authorized ? event.prams_out : null
const otherIn = authorized ? event.other_in : null
const otherOut = authorized ? event.other_out : null
let vehicleLoadRatioText = 'empty'

if (event.vehicle_load_ratio && event.vehicle_load_ratio >= 0.05) {
Expand Down Expand Up @@ -397,6 +406,14 @@ export function createPassengerCountEventObject(
totalPassengersIn,
totalPassengersOut,
vehicleLoadRatioText,
bikesIn,
bikesOut,
wheelchairsIn,
wheelchairsOut,
pramsIn,
pramsOut,
otherIn,
otherOut,
_sort: unix,
}
}
3 changes: 2 additions & 1 deletion src/operators.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"6": "Oy Pohjolan Liikenne Ab",
"7": "Sipoon Linja Oy",
"10": "Oy Liikenne Ab",
"12": "Helsingin Bussiliikenne Oy",
"12": "Koiviston Auto Helsinki Oy",
"17": "Tammelundin Liikenne Oy",
"18": "Oy Pohjolan Kaupunkiliikenne Ab",
"19": "Etelä-Suomen Linjaliikenne Oy",
Expand Down Expand Up @@ -38,6 +38,7 @@
"59": "Tilausliikenne Nikkanen Helsinki Oy",
"60": "Suomenlinnan Liikenne Oy",
"61": "TTS Työtehoseura",
"64": "Taksikuljetus Harri Vuolle Oy",
"89": "Metropolia",
"90": "VR Oy",
"93": "VR-laiturilukijat",
Expand Down
2 changes: 1 addition & 1 deletion src/schema/Alerts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ export const Alerts = gql`
}

type Cancellation {
id: Int!
id: ID!
routeId: String!
direction: Direction!
departureDate: Date!
Expand Down
8 changes: 8 additions & 0 deletions src/schema/Journey.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,14 @@ export const Journey = gql`
totalPassengersIn: Int
totalPassengersOut: Int
vehicleLoadRatioText: String
bikesIn: Int
bikesOut: Int
wheelchairsIn: Int
wheelchairsOut: Int
pramsIn: Int
pramsOut: Int
otherIn: Int
otherOut: Int
_sort: Int
}

Expand Down
9 changes: 8 additions & 1 deletion src/server.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import moment from 'moment-timezone'
import express from 'express'
import rateLimit from 'express-rate-limit'
import cors from 'cors'
import { json } from 'body-parser'
import { ADMIN_GROUP_NAME, COOKIE_SECRET, SECURE_COOKIE, TZ } from './constants'
Expand All @@ -18,6 +19,7 @@ import { getUserFromReq, requireUserMiddleware } from './auth/requireUser'
import { adminController } from './admin/adminController'
import { cleanup } from './utils/cleanup'
import { getKnex } from './knex'

// Set the default timezone for the app
moment.tz.setDefault(TZ)

Expand Down Expand Up @@ -63,13 +65,18 @@ type RequestContext = {

const app = express()

const limiter = rateLimit({
windowMs: 1 * 60 * 1000,
max: 200,
})

app.use(
cors({
credentials: true,
origin: ORIGIN,
})
)

app.use(limiter)
app.use(json({ limit: '50mb' }))

app.engine('js', createEngine({ transformViews: false }))
Expand Down
8 changes: 8 additions & 0 deletions src/types/EventsDb.ts
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,14 @@ export type PassengerCount = {
vehicle_load_ratio: Maybe<number>
total_passengers_in: Maybe<number>
total_passengers_out: Maybe<number>
bikes_in: Maybe<number>
bikes_out: Maybe<number>
wheelchairs_in: Maybe<number>
wheelchairs_out: Maybe<number>
prams_in: Maybe<number>
prams_out: Maybe<number>
other_in: Maybe<number>
other_out: Maybe<number>
}

export type EventsType =
Expand Down
Loading
Loading