This repository contains the code for the web services supporting RikiTraki, an outdoor activities log web application.
The public Web Services and database are hosted entirely in Amazon Web Services (AWS).
Data is maintained in DynamoDB and S3, with Lambda functions providing a secure, schema‑validated CRUD interface via REST APIs.
Unlike the legacy version, this project is not intended for self‑hosting.
All infrastructure is provisioned in AWS using AWS SAM and follows least‑privilege IAM policies.
The project is focused on a managed service model, though the open templates make self‑hosting technically possible if desired.
Key components:
- AWS Lambda: Stateless handlers for tracks, users, authentication, and media.
- Amazon API Gateway (HTTP API): Public REST endpoints with CORS and JWT authorization.
- Amazon DynamoDB: Track metadata and user profiles.
- Amazon S3: GPX files, thumbnails, and full‑resolution pictures.
- JWT Authentication: Tokens issued and verified by Lambda functions.
- CloudWatch Logs: Centralized logging and error monitoring.
Environment variables required by Lambda handlers:
TABLE_NAME– DynamoDB table for track and user metadata.INDEX_NAME– DynamoDB index for track queries.BUCKET_NAME– S3 bucket for GPX and images.JWT_SECRET– Secret for signing and verifying JWT tokens (stored in SSM).JWT_ISSUER– Issuer string for JWT tokens.MAILGUN_API_KEY– Used for user creation and reset flows (stored in SSM).
All handlers are tested with deterministic Jest suites and validated against JSON schemas.
URL Format:
https://<api-id>.execute-api.<region>.amazonaws.com/Prod/{resource}
Example: https://<api-id>.execute-api.us-west-2.amazonaws.com/Prod/tracks
All results are JSON except images and GPX files.
SSL is required for all calls.
Resources
| Resource | Verb | Description | Status Codes | Function Name |
|---|---|---|---|---|
/token |
GET | Retrieves a new JWT token for API calls. Requires basic authentication (username/password). | 200 Success 401 Unauthorized 403 User inactive 500 Server error |
getToken |
/resettoken |
GET | Requests a JWT token via email for password reset. | 200 Success 400 Invalid input 404 User not found 500 Server error |
getResetToken |
/users |
POST | Registers a new user. Requires account activation via email. | 201 Success 400 Invalid input 422 Duplicate 500 Server error |
createUser |
/users/me |
GET | Retrieves user profile info for the JWT token holder. | 200 Success 401 Unauthorized 404 User not found 500 Server error |
getUserInfo |
/users/me |
PUT | Updates user profile info (email and password). Requires basic authentication (username/password). | 204 Success 400 Invalid input 401 Unauthorized 404 User not found 422 Duplicate 500 Server error |
updateUserProfile |
/users/{username} |
PUT | Updates user password. Requires a valid JWT reset token. | 204 Success 400 Invalid input 401 Unauthorized 500 Server error |
resetPassword |
/users/{username}/activation |
PUT | Activates a user account. Requires valid JWT. | 204 Success 400 Invalid input 401 Unauthorized 403 Token mismatch 404 User not found 500 Server error |
activateAccount |
/tracks |
GET | Returns the latest MAX_TRACKS (limit 5000). | 200 Success 404 Not found 500 Server error |
getTracks |
/tracks/number |
GET | Returns the total number of tracks. | 200 Success 500 Server error |
getNumberOfTracks |
/tracks |
POST | Creates a new track. Requires valid JWT. Returns trackId. | 201 Success 400 Invalid input 401 Unauthorized 500 Server error |
createTrack |
/tracks/{trackId} |
GET | Returns a single track. | 200 Success 400 Invalid input 404 Not found 500 Server error |
getTrack |
/tracks/{trackId} |
PUT | Updates track info. Requires valid JWT. | 200 Success 400 Invalid input 401 Unauthorized 404 Not found 500 Server error |
updateTrack |
/tracks/{trackId} |
DELETE | Deletes track and associated images. Requires valid JWT. | 204 Success 401 Unauthorized 403 Forbidden 500 Server error |
deleteTrack |
/tracks/{trackId}/GPX |
GET | Returns GPX file in application/gpx+xml. | 200 Success 404 Not found |
getTrackGPX |
/tracks/{trackId}/geotags |
GET | Returns photo geotags for a track. | 200 Success 404 Not found 500 Server error |
getTrackGeotags |
/tracks/{trackId}/thumbnail/{picIndex} |
GET | Returns thumbnail image (JPEG). | 200 Success 404 Not found |
getThumbnail |
/tracks/{trackId}/picture/{picIndex} |
GET | Returns full‑resolution picture (JPEG). | 200 Success 404 Not found |
getPicture |
/tracks/{trackId}/picture/{picIndex} |
POST | Uploads a picture (JPEG). Requires valid JWT. | 201 Success 401 Unauthorized 413 Too large 500 Server error |
addPicture |
/tracks/{trackId}/picture/{picIndex} |
DELETE | Deletes a picture. Requires valid JWT. | 204 Success 404 Not found 500 Server error |
deletePicture |
/motd |
GET | Returns the five most recent tracks with pictures. | 200 Success 500 Server error |
getMotd |
/loctracks |
GET | Returns tracks near a given location. Accepts lat, lon, and optional username. Computes search radius server‑side and returns up to 200 nearby tracks. If not enough tracks, expands radius to return at least 10 tracks. | 200 Success 400 Bad request 500 Server error |
getTracksByLoc |
/usermotd/{username} |
GET | Returns the five most recent tracks with pictures for a given user. If the user name is ommitted then it is equivalent to /motd (global). | 200 Success 500 Server error |
getUserMotd |
NOTE: RikiTrakiWS (AWS Edition) is in beta.
Self‑hosting is no longer supported; all services run in AWS. Contributions are welcome via pull requests.
To run the test suite locally:
npm install
npm testTests are written with Jest and mock AWS SDK clients for deterministic results. Each handler has a corresponding *.test.mjs file under tests/unit.
Developers interested in contributing are welcome to use their own AWS dev accounts to test and validate changes. These accounts are not managed by the project maintainers. All contributions should be submitted via pull requests, which will be reviewed for alignment with project standards before merging.
This project was developed with the assistance of Microsoft Copilot.