Research
Security News
Malicious npm Packages Inject SSH Backdoors via Typosquatted Libraries
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
@brakebein/nest-neo4j
Advanced tools
This repository provides Neo4j integration for NestJS wrapping the official neo4j-driver.
It is a fork of adam-cowley/nest-neo4j with some changes:
$ npm install @brakebein/nest-neo4j
Register the Neo4j Module in your application using the forRoot
method, passing the Neo4j connection information as an object.
Specific Neo4j settings (refer to neo4j-driver) can be passed via options
.
import { Module } from '@nestjs/common';
import { Neo4jModule } from '@brakebein/nest-neo4j';
import { AppController } from './app.controller';
import { AppService } from './app.service';
@Module({
imports: [
Neo4jModule.forRoot({
scheme: 'neo4j',
host: 'localhost',
port: 7687,
username: 'neo4j',
password: 'neo',
options: {
disableLosslessIntegers: true,
},
verifyConnectionTimout: 60000,
}),
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
Alternatively, you can use forRootAsync
to access information dynamically via ConfigService
:
import { Module } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { Neo4jModule } from '@brakebein/nest-neo4j';
import { AppController } from './app.controller';
import { AppService } from './app.service';
@Module({
imports: [
Neo4jModule.forRootAsync({
useFactory: async (configService: ConfigService) => ({
scheme: configService.get('NEO4J_SCHEME'),
host: configService.get('NEO4J_HOST'),
port: configService.get('NEO4J_PORT'),
username: configService.get('NEO4J_USERNAME'),
password: configService.get('NEO4J_PASSWPRD'),
database: configService.get('NEO4J_DATABASE'),
}),
inject: [ConfigService],
}),
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
If the Neo4j instance is unavailable, connection is not possible.
Driver instantiation will be re-invoked a few times before throwing an error (useful in cases like server startup when node application is live earlier than the Neo4j database instance).
Set verifyConnectionTimeout
to increase the timeout before throwing an error.
The Neo4jService
is @Injectable
, so can be passed into any constructor:
import { Neo4jService } from '@brakebein/nest-neo4j';
@Controller()
export class AppController {
constructor(
private readonly appService: AppService,
private readonly neo4j: Neo4jService,
) {}
@Get()
async getHello(): Promise<any> {
const results = await this.neo4j.read(`MATCH (n) RETURN count(n) AS count`);
return `There are ${results[0].count} nodes in the database`;
}
}
The query results returned by neo4j-driver are mapped to objects that correlate with identifiers within the RETURN
clause and the node's properties.
To access the raw query results, use the respective methods, e.g. .readRaw()
.
.read(cypher: string, params?: Record<string, any>, database?: string)
A very simple read transaction that expects a cypher statement and (optionally) query parameters.
Returns an array of objects, where the object's property names correlate with identifiers within the RETURN
clause.
const query = `
MATCH (p:Person {name: $name})-[:HAS_ADDRESS]->(add:Address)
RETURN p.name AS name, add AS address
`;
const params = {
name: 'Alex'
};
const results = await this.neo4j.read(query, params);
console.log(results);
// console.log(results)
// [
// {
// name: 'Alex',
// address: {
// ZIP: '10178',
// number: '1',
// town: 'Berlin',
// street: 'Alexanderplatz'
// }
// }
// ]
Use .readRaw()
to get the raw query results.
.write(cypher: string, params?: Record<string, any>, database?: string)
Very similar to .read()
(see for details) except that it expects a cypher statement that modifies the database.
Use .writeRaw()
to get the raw query results.
.multipleStatements(statements: { statement: string; parameters: Record<string, any> }[])
Execute multiple cypher queries within one transaction. A fail of one statement will lead to the rollback of the whole transaction.
Returns an array of arrays of objects (similar to .read()
or .write()
).
const statements = [{
statement: `CREATE ...`,
parameters: {}
}, {
statement: `MATCH ... CREATE (n:Node $map) ...`,
parameters: { map: { value: 'foo' } }
}];
const results = await this.neo4j.multipleStatements(statements);
// handle results
Use .multipleStatementsRaw()
to get an array of the raw query results.
.getDriver()
Get the driver instance to access the full API of neo4j-driver.
.getConfig()
Get configuration as provided with Neoj4Module
.
.getReadSession(database?: string)
Acquire a READ session to execute, e.g., explicit transactions.
.getWriteSession(database?: string)
Acquire a WRITE session to execute, e.g., explicit transactions.
.extractRecords<T = any>(data: Record[]): T[]()
Used internally to extract and convert the returned records by neo4j-driver to a more simplified format. It converts non-standard values, like date, time, etc., to strings as well as Neo4j integers, if they are outside the safe range.
Takes an array of Neo4j records Record[]
and returns an array of objects.
import { Neo4jService } from './neo4j.service';
const query = `
MATCH (p:Person {name: "Alex"})-[:HAS_ADDRESS]->(add:Address)
RETURN p.name AS name, add AS address
`;
// query results returned by neo4j-driver
// {
// records: [
// Record {
// keys: [ 'name', 'address' ],
// length: 2,
// _fields: [
// 'Alex',
// Node {
// identity: 1,
// labels: [ 'Address' ],
// properties: {
// ZIP: '10178',
// number: '1',
// town: 'Berlin',
// street: 'Alexanderplatz'
// }
// }
// ]
// _fieldLookup: { name: 0, address: 1 }
// }
// ],
// summary: ResultSummary {...}
// }
extractRecords(queryResults.records);
// simplified records returned by neo4j-request
// {
// name: 'Alex',
// address: {
// ZIP: '10178',
// number: '1',
// town: 'Berlin',
// street: 'Alexanderplatz'
// }
// }
.removeEmptyArrays<T>(data: T[], arrayKey: string, checkKey: string): T[]
Look for empty arrays returned by Neo4j and clean them, if there is null
inside.
Sometimes, if the cypher query contains OPTIONAL MATCH node
in combination with collect({key: node.value}) AS values
, the resulting array may be filled with one object with null
values: [{key: null}]
. This method reduces the array to []
by calling removeEmptyArrays(data, 'values', 'key')
.
const query = `
MATCH (p:Person {name: "Alex"})-[:HAS_ADDRESS]->(add:Address)
OPTIONAL MATCH (p)-[:HAS_FRIEND]->(f:Person)-[:HAS_ADDRESS]->(fAddr:Address)
RETURN p.name AS name,
add AS address,
collect({name: f.name, address: fAddr}) AS friends
`;
const results = await this.neo4j.read(query);
console.log(results);
// [
// {
// name: 'Alex',
// address: {
// ZIP: '10178',
// number: '1',
// town: 'Berlin',
// street: 'Alexanderplatz'
// },
// friends: [ { address: null, name: null } ]
// }
// ]
const resultsCleaned = this.neo4j.removeEmptyArrays(results, 'friends', 'name');
console.log(resultsCleaned);
// [
// {
// name: 'Alex',
// address: {
// ZIP: '10178',
// number: '1',
// town: 'Berlin',
// street: 'Alexanderplatz'
// },
// friends: []
// }
// ]
FAQs
Neo4j integration for NestJS
We found that @brakebein/nest-neo4j demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
Security News
MITRE's 2024 CWE Top 25 highlights critical software vulnerabilities like XSS, SQL Injection, and CSRF, reflecting shifts due to a refined ranking methodology.
Security News
In this segment of the Risky Business podcast, Feross Aboukhadijeh and Patrick Gray discuss the challenges of tracking malware discovered in open source softare.