Research
Security News
Malicious npm Package Targets Solana Developers and Hijacks Funds
A malicious npm package targets Solana developers, rerouting funds in 2% of transactions to a hardcoded address.
Data-agnostic admin interface generator for CRUD applications
Note from Sam: This idea exists almost totally in concept. There is alpha code being written, but it's very rudimentary at this point and is not guaranteed to work at all. I've published to NPM only so that the name is reserved.
The problem with crud apps is they are all are basically the same, yet we find it necessary to always rewrite the same code over and over. We have a set of requirements that remain relatively constant:
In addition, we always have data coming in from somewhere. Sometimes it's all from a database, sometimes it's from flat files, and even sometimes it's from the network. The problem with other frameworks is they are all dependent (or completely revolve around) on one type of data retrieval, usually a database.
npm install acp
var acp = require('acp');
var adm = acp();
adm.listen(3000); // identical to express's app.listen()
Because acp is an express application, we can simply mount it on top of another application currently being set up. This allows you to write your own custom user-facing front-end and acp to mange your data behind.
var adm = acp();
var app = express();
// ...
app.use('/admin', adm); // mount on "admin"
app.listen(3000); // do not listen with adm
A collection is any set of data that you wish to manage. You can pull it from your database, flat files, remote systems, etc.
var acp = require('acp');
var adm = acp();
var userCollection = adm.define('Users', {
primaryKey: 'id', // defaults to 'id'
mount: 'auto', // defaults to 'auto. Mounts CRUD pages on url-safe version of the collection name
create: createUser,// function(record, cb) , cb(err, record),
readOne: getOneUser,// function ( primaryKey ),
read: getUsers, // function( { start: 0, limit: 10 }),
update: updateUser, // function ( primaryKey, record ),
delete: deleteUser, // function ( primaryKey | record ), cb(Error err, bool deleted)
count: countUsers, // function (cb), cb(Error err, number count),
fields: {
id: { type: 'auto', primary: true }, // auto_int sets nice defaults
slug: { type: 'string', filter: [ ACP.Filter.urlSafe, },
name: { type: 'string', validate: function (n) {
return /[a-z0-9_\-]{4,10}/i.test(n);
}},
email: { type: 'string', validate: [ ACP.Validate.email, function (email, next) { // validate can take an array
db.query('SELECT * FROM users WHERE email = ?', [ email ], function (err, rows) {
if (err) throw err;
next( !rows.length );
});
}]}
}
});
adm.listen(3000);
var acp = require('acp');
var admin = acp();
// same arguments as .define()
admin.page('Dashboard', {
mount: '/',
widgets: [ // table of widgets
[w1, w2, w3],
[w4, w5]
]
});
ACP
This is the main class of the Admin Control Panel Interface.
Extends EventEmiter
ACP.define(name, options)
Defines a collection of data to keep track of
name
String: Name of the collection, usually pularoptions
Object:
primaryKey
String: Field name of the primary key.disableCrud
Boolean: (optional) Disable crud functionality? default:
falsemount
String: (optional) 'auto' to mount on root with generated slug
(default), '/routname' otherwise.orderedBy
String: (optional) Field name to order by if ordered list.
false or null otherwise. Default: falsecreate
Function: callback to store a new record.
Params: record
, callback(err, record
)update
Function: callback to update a record.
Params: record
, callback (err, record)
readOne
Function: callback to read one record.
Params: primaryKey
, callback(err, record)
read
Function: callback to get the collection.
Params: filter
Array< ACP.Filter >, callback(err, recs)
delete
Function callback to delete a record.
Params: primaryKey
, callback(err, deleted?)
count
Function callback to count all records.
Params: Array<ACP.Filter>, callback(err, count)
fields
Array<ACP.Field>: Field ListACP.page(name, options)
name
String: Name of the pageoptions
Object:
mount
String: (optional) 'auto' to mount on root with generated slug
(default), '/routname' otherwise.widgets
Array< Array<ACP.Widget> >: Widget table. Outer Array: Rows;
inner Array: ColumnsACP.Filter
Plain object.
field_name
Object:
eq
Mixed: Returned values must be equal.ne
Mixed: Returned values must not be equalgt
Mixed: Returned values must be greater thanlt
Mixed: Returned values must be less thangte
Mixed: Returned values must be greater than or equalslte
Mixed: Returns values must be less than or equalsFor example:
{ email: { ne: 'user@example.com '} }
ACP.Field
Is just a plain object with the following properties:
type
String: 'auto', 'number', 'string', 'text', 'bool', 'datetime', 'date'primary
Boolean: Is primary key? Default: false. Overridden if primaryKey is set in collectioneditable
Boolean: Can the user edit this field?filter
Function|Array: Filter (modify values) of the recordvalidate
Function|Array: Validate a field. performed AFTER filtersoptions
Array|Plain Object: (Optional) if this is a dropdown/radio/checkbox list, anyinput
Flag: ACP.TEXT, ACP.PASSWORD, ACP.EMAIL, ACP.DROPDOWN,
ACP.DROPDOWN_MULI, ACP.DATE_PICKER, ACP.DATETIME_PICKER, ACP.RADIO, ACP.CHECKBOXACP.Widget
Plain object with properties:
size
Number: 1-12, grid width. Default: 3template
String: Either a built in template or user-defined custom pathread
Function: Callback to read data to populate the widget widthtitle
String: Widget titleACP.Filter
Contains the functions to validate automatically
ACP.Filter.urlSafe
: Makes a URL safe string (RFC 3986)ACP.Filter.slug
: Makes the string into a clean URL-safe sting [a-z0-9-_]ACP.Filter.boolean
: Converts strings from s "1" or "0" into true boolean valuesACP.Filter.datetime
: Parses the date to an ISO 8601 compliant stringACP.Filter.jsDate
: Turns field into a JavaScript Date
objectACP.Validate
Contains the functions to validate automatically
ACP.Validate.email
: Validates an emailACP.Validate.url
: Validates a URLACP.Validate.foreignKey(collectionName)
: Validates that there exists a primary key in the collectionACP.Validate.unique
: Validates that there are no records with the same value in this fieldWhen you create a collection, you specify where the data comes from, how it is inserted, how it is updated, and what validations need to take place. There are validation macros you can use for extremely common validations, such as email addresses, url-safe strings, and checking for duplicates in other models. You may also specify filters which take data pre-validation and operate on it.
You don't have to write your own views. You specify where and when you want things to appear and it just makes it for you.
To make hooking it into your stack easier, it is made to either piggy-back off of your current express application or you can specify to run it standalone.
Because this is going to give a user a one-stop-shop for mangling the database, we wanted to ensure only the people you give access will have access. There are few layers of security we've added on:
The MIT License
FAQs
Data-agnostic admin interface generator for CRUD applications
We found that acp demonstrated a not healthy version release cadence and project activity because the last version was released 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
A malicious npm package targets Solana developers, rerouting funds in 2% of transactions to a hardcoded address.
Security News
Research
Socket researchers have discovered malicious npm packages targeting crypto developers, stealing credentials and wallet data using spyware delivered through typosquats of popular cryptographic libraries.
Security News
Socket's package search now displays weekly downloads for npm packages, helping developers quickly assess popularity and make more informed decisions.