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.
stargate-mongoose
Advanced tools
stargate-mongoose
is a Mongoose driver for Data API which runs on top of Apache Cassandra / DataStax Enterprise.
Prerequisites: node (>=14.0.0), npm/yarn, Docker (for testing the sample app locally using docker compose)
Docker
on your local machine.git clone https://github.com/stargate/stargate-mongoose.git
cd stargate-mongoose
For macOS/Linux
bin/start_data_api.sh
For Windows
bin\start_data_api.cmd
mkdir sample-app
cd sample-app
npm init -y && npm install express mongoose stargate-mongoose --engine-strict
OR
yarn init -y && yarn add express mongoose stargate-mongoose
index.js
under the 'sample-app' directory and copy below code into the file.//imports
const express = require('express');
const mongoose = require('mongoose');
const stargate_mongoose = require('stargate-mongoose');
const Schema = mongoose.Schema;
const driver = stargate_mongoose.driver;
//override the default native driver
mongoose.setDriver(driver);
//Set up mongoose & end points definition
const Product = mongoose.model('Product', new Schema({ name: String, price: Number }));
mongoose.connect('http://localhost:8181/v1/inventory', {
username: 'cassandra',
password: 'cassandra'
});
Object.values(mongoose.connection.models).map(Model => Model.init());
const app = express();
app.get('/addproduct', (req, res) => {
const newProduct = new Product(
{
name: 'product' + Math.floor(Math.random() * 99 + 1),
price: '' + Math.floor(Math.random() * 900 + 100)
});
newProduct.save();
res.send('Added a product!');
});
app.get('/getproducts', (req, res) => {
Product.find()
.then(products => res.json(products));
});
//Start server
const HOST = '0.0.0.0';
const PORT = 8097;
app.listen(PORT, HOST, () => {
console.log(`Running on http://${HOST}:${PORT}`);
console.log('http://localhost:' + PORT + '/addproduct');
console.log('http://localhost:' + PORT + '/getproducts');
});
node index.js
docker compose -f bin/docker-compose.yml down -v
The current implementation of the Data API uses DataStax Enterprise (DSE) as the backend database.
Component/Library Name | Version |
---|---|
Mongoose | ^7.5.0 || ^8.0.0 |
data-api | 1.x |
DataStax Enterprise | 6.8.x |
CI tests are run using the Stargate and Data API versions specified in the api-compatibility.versions file.
Here's a quick way to connect to AstraDB using stargate-mongoose
driver.
const mongoose = require("mongoose");
const { driver, createAstraUri } = require("stargate-mongoose");
const uri = createAstraUri(
process.env.ASTRA_DB_API_ENDPOINT,
process.env.ASTRA_DB_APPLICATION_TOKEN,
process.env.ASTRA_DB_NAMESPACE // optional
);
mongoose.setDriver(driver);
await mongoose.connect(uri, {
isAstra: true,
});
And the step-by-step instructions with a sample application can be found here in below guide.
https://docs.datastax.com/en/astra/astra-db-vector/api-reference/data-api-with-mongoosejs.html
Sample applications developed using stargate-mongoose
driver are available in below repository.
https://github.com/stargate/stargate-mongoose-sample-apps
Operation Name | Description |
---|---|
createDatabase | When flag createNamespaceOnConnect is set to true the keyspace passed on to the mongoose.connect function via the URL, is created automatically |
dropDatabase | Drops the database |
createCollection | mongoose.model('ModelName',modelSchema) creates a collection as required |
dropCollection | model.dropCollection() drops the collection |
Operation Name | Description |
---|---|
countDocuments | Model.countDocuments(filter) returns the count of documents |
deleteMany | Model.deleteMany(filter) . This API will throw an error when more than 20 records are found to be deleted. |
deleteOne | Model.deleteOne(filter, options) options - sort |
find | Model.find(filter, projection, options) options - limit , pageState , skip , sort (skip works only with sorting) |
findOne | Model.findOne(filter, options) options - sort Example: findOne({}, { sort: { username: -1 } }) |
findOneAndDelete | Model.findOneAndDelete(filter, options) options - sort |
findOneAndReplace | Model.findOneAndReplace(filter, replacement, options) options upsert: (default false )true - if a document is not found for the given filter, a new document will be inserted with the values in the filter (eq condition) and the values in the $set and $setOnInsert operators.false - new document will not be inserted when no match is found for the given filter-------- returnDocument : (default before )before - Return the document before the changes were appliedafter - Return the document after the changes are applied |
findOneAndUpdate | Model.findOneAndUpdate(filter, update, options) options upsert: (default false )true - if a document is not found for the given filter, a new document will be inserted with the values in the filter (eq condition) and the values in the $set and $setOnInsert operators.false - new document will not be inserted when no match is found for the given filter-------- returnDocument : (default before )before - Return the document before the changes were appliedafter - Return the document after the changes are applied |
insertMany | Model.insertMany([{docs}], options) In a single call, only 20 records can be inserted. options - ordered |
insertOne | Model.insertOne({doc}) |
updateMany | Model.updateMany(filter, update, options) options upsert: (default false )true - if a document is not found for the given filter, a new document will be inserted with the values in the filter (eq condition) and the values in the $set and $setOnInsert operators.false - new document will not be inserted when no match is found for the given filter** This API will throw an error when more than 20 records are found to be updated. |
updateOne | Model.updateOne(filter, update, options) options upsert: (default false )true - if a document is not found for the given filter, a new document will be inserted with the values in the filter (eq condition) and the values in the $set and $setOnInsert operators.false - new document will not be inserted when no match is found for the given filter-------- returnDocument : (default before )before - Return the document before the changes were appliedafter - Return the document after the changes are applied |
Operator | Description |
---|---|
literal comparison | Equal to. Example: { 'first_name' : 'jim' } |
$eq | Example: { 'first_name' : { '$eq' : 'jim' } } |
$gt | Example (age > 25): { 'age' : { '$gt' : 25 } } |
$gte | Example (age >= 25): { 'age' : { '$gte' : 25 } } |
$lt | Example (age < 25): { 'age' : { '$lt' : 25 } } |
$lte | Example (age <= 25): { 'age' : { '$lte' : 25 } } |
$ne | Example: { 'first_name' : { '$ne' : 'jim' } } |
$in | Example: { '_id' : { '$in' : ['nyc', 'la'] } } $in is not supported in non _id columns at the moment |
$nin | Example: { 'address.city' : { '$nin' : ['nyc', 'la'] } } |
$not | Not supported. Example: { 'first_name' : { '$not' : { '$eq' : 'jim' }}} |
$exists | Example: { 'address.city' : { '$exists' : true} } |
$all | Array operation. Matches if all the elements of an array matches the given values. Example: { 'tags' : { '$all' : [ 'home', 'school' ] } } |
$elemMatch | Not supported. Matches if the elements of an array in a document matches the given conditions. Example: {'goals': { '$elemMatch': { '$gte': 2, '$lt': 10 }}} |
$size | Array Operation. Example: { 'tags' : { '$size' : 1 } } |
$and (implicit) | Logical expression. Example : { '$and' : [ {first_name : 'jim'}, {'age' : {'$gt' : 25 } } ] } |
$and (explicit) | Example : { '$and' : [ {first_name : 'jim'}, {'age' : {'$gt' : 25 } } ] } |
$or | Example: { '$or' : [ {first_name : 'jim'}, {'age' : {'$gt' : 25 } } ] } |
Operator | Description |
---|---|
$elemMatch (projection) | Not supported |
$slice | Array related operation. Example: { 'tags' : { '$slice': 1 }} returns only the first element from the array field called tags. |
$ (projection) | Example: Model.find({}, { username : 1, _id : 0}) - This returns username in the response and the _id field |
Operator | Description |
---|---|
Single Field Sort | Supported |
Multi Field Sort | Not supported |
Operator | Description |
---|---|
$inc | Example: { '$inc': { 'points' : 5 } } |
$min | Example: { 'col': { '$min' : 5 } } if the columns value is greater than 5, it will be updated with 5 |
$max | Example: { 'col': { '$max' : 50 } } if the columns value is lesser than 50, it will be updated with 50 |
$rename | Example: { $rename: { '$max' : 50 } } if the columns value is lesser than 50, it will be updated with 50 |
$set | Example: {'update' : {'$set': {'location': 'New York'} }} |
$setOnInsert | Example: {'update' : {'$set': {'location': 'New York'}, '$setOnInsert': {'country': 'USA'} }} |
$unset | Example: {'update' : {'$unset': [address.location] }} |
$addToSet | Example: {'$addToSet' : {'points': 10}} . This will add 10 to an array called points in the documents, without duplicates (i.e. ll skip if 10 is already present in the array) |
$pop | Example: {'$pop' : {'points': 1 }} . This removes the last 1 item from an array called points . -1 will remove the first 1 item. |
$pull | Not supported |
$push | Example. '$push': {'tags': 'work'} . This pushes an element called work to the array tags |
$pullAll | Not supported |
Index operations are not supported. There is one caveat for ttl
indexes: When adding a document, you can add a ttl
option (determined in seconds) that will behave in the similar way to a ttl
index. For example, with the collection's client:
import { Client } from 'stargate-mongoose';
// connect to Data API
const client = await Client.connect(process.env.DATA_API_URI);
// get a collection
const collection = client.db().collection('docs');
// insert and expire this document in 10 seconds
await collection.insertOne({ hello: 'world' }, { ttl: 10 });
Aggregation operations are not supported.
Transaction operations are not supported.
If you have an application that uses the NodeJS MongoDB driver, or a dependency that uses the NodeJS MongoDB driver, it is possible to override its use with the collections package of stargate-mongoose
. This makes your application use Data API documents instead of MongoDB documents. Doing so requires code changes in your application that address the features section of this README, and a change in how you set up your client connection.
If your application uses mongodb
you can override its usage like so:
In your app's mongodb
package.json
entry:
"mongodb": "stargate-mongoose@0.2.0-ALPHA-3",
Then, re-install your dependencies
npm i
Finally, modify your connection so that your driver connects to Data API
import { MongoClient } from 'stargate-mongoose';
// connect to Data API
const client = await MongoClient.connect(process.env.DATA_API_URI);
If you have an application dependency that uses mongodb
, you can override its usage like so (this example uses mongoose
):
Add an override to your app's package.json
(requires NPM 8.3+), also, add `stargate-mongoose as a dependency:
"dependencies": {
"stargate-mongoose": "^0.2.0-ALPHA-3"
},
"overrides": {
"mongoose": {
"mongodb": "stargate-mongoose@0.2.0-ALPHA-3"
}
},
Then, re-install your dependencies
npm i
Finally, modify your dependencies connection so that your driver connects to Data API
import mongoose from 'mongoose';
// connect to Data API
await mongoose.connect(process.env.DATA_API_URI);
FAQs
Stargate's NodeJS Mongoose compatability client
The npm package stargate-mongoose receives a total of 227 weekly downloads. As such, stargate-mongoose popularity was classified as not popular.
We found that stargate-mongoose demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers 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.