NOTICE: This is an early stage project and should only be operated in secure, trusted environments
Cartographer is the open-source reference implementation of Sodal's Persona Graph model for agency management. Cartographer demonstrates how persona graphs enable discovery and management of identities and resources (and associated collaboration opportunities and risks) without the need for comprehensive controls or top-down policy enforcement.
Cartographer is a self-contained application that can run locally or on docker-compatible cloud infrastructure. Cartographer uses a Node/Express server. The server stores graph data in a Neo4j database and object data in a MongoDB database.
- Modules - developing and working with modules
- Components - developing and working with components
- Install Docker for your platform.
- Copy the .env.example file to .env
The default configuration uses ports 3000, 7474, 7687, 28000
This terminal command will start the app and database. The first time it runs it will need to download files which may take several minutes.
docker-compose upThe processes will run in a single terminal window (they are color coded). You can view the front end by visiting http://localhost:3000 in your browser window.
The open-source "Core" system offers fundamental tools for working with a graph database and includes MongoDB for handling additional data. It supports creating modules that ingest, format, store, and display graph data.
- The components folder contains handlebars partials
- There is a folder called icons that contains SVG icons
- Partials should not contain a script tag with javascript as that will load multiple times, instead functions needed by components should be placed in the main.js file.
- Using JWT
To generate a value for the ACCESS_TOKEN_SECRET and the REFRESH_TOKEN_SECRET in .env
- Open a terminal window and type node followed by the enter key to enter the Node REPL
- Run this
require('crypto').randomBytes(64).toString('hex') - Use the resulting value for ACCESS_TOKEN_SECRET and run again for the REFRESH_TOKEN_SECRET
The project uses Jest for testing. Tests are located in the tests/ directory and follow the same structure as the source code.
# Run all tests once
npm test
# Run tests in watch mode (recommended during development)
npm run test:watch
# Run tests with coverage report
npm run test:coverage- Tests use the primary Neo4j database instance
- Only test data is cleared between tests using
db.clear()- Clears all items with
upn:test:*andsource:test:*namespaces - Does not affect live module data
- Clears all items with
- Test data is loaded from fixtures in
tests/core/fixtures/ - Test data naming conventions:
- Use
upn:test:*for test personas - Use
source:test:*for test sources - These namespaces are reserved for test data and will be purged between tests
- Do not use these namespaces in live modules
- Use
-
Test Structure
import { db } from './setup/db.js'; import graph from '../../core/graph.js'; describe('My Test Suite', () => { beforeAll(async () => { await db.initialize(); }); beforeEach(async () => { await db.clear(); // Clears only test namespace data await db.setup(); // Loads test fixtures }); afterAll(async () => { await db.close(); }); it('should do something', async () => { // Test code here // Use upn:test:* and source:test:* for test data // Live module data will remain untouched }); });
-
Database Utilities
db.initialize()- Set up database connectiondb.clear()- Clear only test namespace data (upn:test:* and source:test:*)db.setup()- Load test fixturesdb.close()- Close database connection
-
Best Practices
- Use
beforeAllto initialize the database connection - Use
beforeEachto clear and reset test data - Use
afterAllto clean up - Always use
upn:test:*andsource:test:*for test data - Never use test namespaces in live modules
- Test both success and error cases
- Use descriptive test names
- Keep tests focused and isolated
- Use
When using npm run test:watch:
- Tests run automatically when files change
- Press
ato run all tests - Press
fto run only failed tests - Press
pto filter by filename pattern - Press
tto filter by test name pattern - Press
qto quit watch mode
| Name | Description | License |
|---|---|---|
| bcrypt | Password hashing library | MIT |
| cookie-parser | Parse Cookie header and populate req.cookies | MIT |
| dotenv | Loads environment variables from .env file | BSD-2-Clause |
| express | Fast, unopinionated, minimalist web framework | MIT |
| express-handlebars | A Handlebars view engine for Express | BSD-3-Clause |
| jsonwebtoken | JSON Web Token implementation | MIT |
| mongodb | The official MongoDB driver for Node.js | Apache-2.0 |
| multer | Middleware for handling multipart/form-data | MIT |
| neo4j-driver | Official Neo4j driver for JavaScript | Apache-2.0 |
| nodemon | Simple monitor script for use during development | MIT |
| sanitize-filename | Sanitize a string to be safe for use as a filename | WTFPL, ISC |
| ws | Simple and fast WebSocket client and server | MIT |
| Name | Description | License |
|---|---|---|
| @babel/preset-env | Babel preset for all latest JavaScript features | MIT |
| @eslint/js | ESLint JavaScript configuration | MIT |
| eslint | JavaScript linting utility | MIT |
| globals | Global identifiers from different JavaScript environments | MIT |
| jest | JavaScript Testing Framework | MIT |
| jest-environment-node | Node environment for Jest | MIT |
| typescript-eslint | TypeScript support for ESLint | MIT |