
Research
/Security News
Critical Vulnerability in NestJS Devtools: Localhost RCE via Sandbox Escape
A flawed sandbox in @nestjs/devtools-integration lets attackers run code on your machine via CSRF, leading to full Remote Code Execution (RCE).
fms-api-client
Advanced tools
A FileMaker Data API client designed to allow easier interaction with a FileMaker application from a web environment.
A FileMaker Data API client designed to allow easier interaction with a FileMaker application from a web environment. This client abstracts the FileMaker 17 Data API into class based methods. You can find detailed documentation on this project here:
npm install --save fms-api-client
The fms-api-client is a wrapper around the FileMaker Data API. Much :heart: to FileMaker for their work on the Data API. The client attempts to follow the terminology used by FileMaker wherever possible. the client uses a lightweight datastore to hold Data API connections. The client contains methods which are modeled after the Data API Endpoints.
Connect must be called before the filemaker class is instiantiated. This connect uses Marpat.Marpat is a fork of Camo. Thanks and love to Scott Robinson for his creation and maintenance of Camo. My fork of Camo - Marpat is designed to allow the use of multiple datastores with the focus on encrypted file storage.
For more information on marpat and the different types of supported storage visit marpat
connect('nedb://memory')
Excerpt from ./examples/index.js
After connecting to a datastore you can import and create clients. A client is created using the create method on the client class. The client requires a server and application to connect to as well as valid credentials. Note that the server must be an http or https domain.
const client = Filemaker.create({
application: process.env.APPLICATION,
server: process.env.SERVER,
user: process.env.USERNAME,
password: process.env.PASSWORD
});
Excerpt from ./examples/index.js
A client can be used directly after saving it. It is also stored on the datastore so that it can be reused later.
return client
.save()
.then(client => authentication(client))
.then(client => creates(client))
.then(client => lists(client))
.then(client => finds(client))
.then(client => edits(client))
.then(client => scripts(client))
.then(client => globals(client))
.then(client => deletes(client))
.then(client => uploads(client))
.then(client => utilities(client));
Excerpt from ./examples/index.js
All public methods on the client are promises. You can chain together multiple calls.
const createManyRecords = client =>
Promise.all([
client.create('Heroes', { name: 'Anakin Skywalker' }, { merge: true }),
client.create('Heroes', { name: 'Obi-Wan' }, { merge: true }),
client.create('Heroes', { name: 'Yoda' }, { merge: true })
]).then(result => log('create-many-records', result));
Excerpt from ./examples/create.examples.js
Results:
[
{
"name": "Anakin Skywalker",
"recordId": 729077,
"modId": 0
},
{
"name": "Obi-Wan",
"recordId": 729073,
"modId": 0
},
{
"name": "Yoda",
"recordId": 729075,
"modId": 0
}
]
The client contains two methods related to authentication. The client has an authenticate method and the logout method.
The authenticate method is used to start a FileMaker user session and generate an authentication. The client will automatically call the authenticate method if it does not have a valid token. This method returns a string rather than an object. The string returned is the authentication token. This method will also save the token to the client's connection for future use.
Note The authenticate will change in an upcoming release. It will be modified to return an object.
const login = client => client.authenticate();
Excerpt from ./examples/authentication.examples.js
The logout method is used to close a FileMaker User session. This method will also remove the current client's authentication token.
Note The logout method will change in an upcoming release. It will be modified to accept a session parameter.
const logout = client =>
client.logout().then(result => log('client-logout-example', result));
Excerpt from ./examples/authentication.examples.js
Using the client you can create filemaker records. To create a record specify the layout to use and the data to insert on creation. The client will automatically convert numbers, arrays, and objects into strings so they can be inserted into a filemaker field.
const createRecord = client =>
client
.create('Heroes', {
name: 'George Lucas'
})
.then(result => log('create-record', result));
Excerpt from ./examples/create.examples.js
Result:
{
"recordId": 729074,
"modId": 0
}
The create method accepts the option of merge. If merge is true the data used to create the with DAPI's response object on success.
const mergeDataOnCreate = client =>
client
.create(
'Heroes',
{
name: 'George Lucas'
},
{ merge: true }
)
.then(result => log('create-record-merge', result));
Excerpt from ./examples/create.examples.js
Result:
{
"name": "George Lucas",
"recordId": 729072,
"modId": 0
}
The create methods also allows you to trigger scripts when creating a record. Notice the scripts property in the following example. You can specify scripts to run using either FileMaker's script.key syntax or specify an array of scripts with a name, phase, and script parameter.
const triggerScriptsOnCreate = client =>
client
.create(
'Heroes',
{ name: 'Anakin Skywalker' },
{
merge: true,
scripts: [
{ name: 'Create Droids', param: { droids: ['C3-PO', 'R2-D2'] } }
]
}
)
.then(result => log('trigger-scripts-on-create', result));
Excerpt from ./examples/create.examples.js
Result:
{
"name": "Anakin Skywalker",
"scriptError": 0,
"recordId": 729076,
"modId": 0
}
You can use the client to list filemaker records. The list method accepts a layout and parameter variable. The client will automatically santize the limit, offset, and sort keys to correspond with the DAPI's requirements.
const listHeroes = client =>
client
.list('Heroes', { limit: 5 })
.then(result => log('list-records-example', result));
Excerpt from ./examples/list.examples.js
Result:
{
"data": [
{
"fieldData": {
"id": "91C249FB-2127-8B47-9FBD-A4B004D95D5F",
"name": "Yoda",
"image(1)": "https://some-server.com/Streaming_SSL/MainDB/07680AA37D5FF57418036B4A1664401C5ED1C192845407761F52BDE15DAD2D7A?RCType=EmbeddedRCFileProcessor",
"object": "",
"array": "",
"height": "",
"image(2)": ""
},
"portalData": {
"planets": []
},
"recordId": "729057",
"modId": "1"
},
{
"fieldData": {
"id": "921B1983-2AC9-3647-9EC9-1C99F5BC7259",
"name": "Darth Vader",
"image(1)": "",
"object": "",
"array": "",
"height": "",
"image(2)": ""
},
"portalData": {
"planets": []
},
"recordId": "729058",
"modId": "1"
},
{
"fieldData": {
"id": "97A3CF0E-869C-EF42-821D-AF59AF650BD9",
"name": "Obi-Wan",
"image(1)": "",
"object": "",
"array": "",
"height": "",
"image(2)": ""
},
"portalData": {
"planets": []
},
"recordId": "729061",
"modId": "0"
},
{
"fieldData": {
"id": "8AFDEF46-0481-5644-8683-95EC04810BE1",
"name": "",
"image(1)": "https://some-server.com/Streaming_SSL/MainDB/691AF27E7EBA2A7BF58E2F52BD4756C46C9301CF7CCE14214C6763EEEF500423?RCType=EmbeddedRCFileProcessor",
"object": "",
"array": "",
"height": "",
"image(2)": ""
},
"portalData": {
"planets": []
},
"recordId": "729064",
"modId": "1"
},
{
"fieldData": {
"id": "BBA9D269-0089-F142-ABCA-A3194836C5D3",
"name": "George Lucas",
"image(1)": "",
"object": "",
"array": "",
"height": "",
"image(2)": ""
},
"portalData": {
"planets": []
},
"recordId": "729065",
"modId": "0"
}
]
}
The client's find method will accept either a single object as find parameters or an array. The find method will also santize the limit, sort, and offset parameters to conform with the Data API's requirements.
const findRecords = client =>
client
.find('Heroes', [{ name: 'Anakin Skywalker' }], { limit: 1 })
.then(result => log('find-records-example', result));
Excerpt from ./examples/find.examples.js
Result:
{
"data": [
{
"fieldData": {
"id": "A63A76F7-804E-C24A-BDB8-53B38598877C",
"name": "Anakin Skywalker",
"image(1)": "",
"object": "",
"array": "",
"height": "",
"image(2)": ""
},
"portalData": {
"planets": []
},
"recordId": "729067",
"modId": "0"
}
]
}
The client's edit method requires a layout, recordId, and object to use for updating the record.
const editRecords = client =>
client
.find('Heroes', [{ name: 'Anakin Skywalker' }], { limit: 1 })
.then(response => response.data[0].recordId)
.then(recordId => client.edit('Heroes', recordId, { name: 'Darth Vader' }))
.then(result => log('edit-record-example', result));
Excerpt from ./examples/edit.examples.js
Result:
{
"modId": 1
}
The client's delete method requires a layout and a record id.
const deleteRecords = client =>
client
.find('Heroes', [{ name: 'yoda' }], { limit: 1 })
.then(response => response.data[0].recordId)
.then(recordId => client.delete('Heroes', recordId))
.then(result => log('delete-record-example', result));
Excerpt from ./examples/delete.examples.js
Result:
{}
The client's script method requires a script to run and a layout to run on.
Note The trigger script parameter order while change in a future release. It will be modified to swap the script name parameter with the layout parameter.
const triggerScript = client =>
client
.script('FMS Triggered Script', 'Heroes', { name: 'Han' })
.then(result => log('script-trigger-example', result));
Excerpt from ./examples/script.examples.js
Result:
{
"result": {
"answer": "Han shot first"
}
}
The client's upload method will upload file data to a filemaker file. The upload method requires a file path, layout, and container field name.
const uploadImage = client =>
client
.upload('./assets/placeholder.md', 'Heroes', 'image')
.then(result => log('upload-image-example', result));
Excerpt from ./examples/upload.examples.js
Result:
{
"modId": 1
}
You can also provide a record Id to the upload method and the file will be uploaded to that record.
const uploadSpecificImage = client =>
client
.find('Heroes', [{ name: 'yoda' }], { limit: 1 })
.then(response => response.data[0].recordId)
.then(recordId =>
client.upload('./assets/placeholder.md', 'Heroes', 'image', recordId)
)
.then(result => log('upload-specific-record-example', result));
Excerpt from ./examples/upload.examples.js
Result:
{
"modId": 1
}
You can also use the client to set FileMaker Globals for the session.
const setGlobals = client =>
client
.globals({ 'Globals::ship': 'Millenium Falcon' })
.then(result => log('set-globals-example', result));
Excerpt from ./examples/globals.examples.js
Result:
{}
The client also provides helper methods to aid in parsing and manipulating FileMaker Data. There are currently to helper methods.
The recordId method takes either an object or an array of objects with recordId properties and returns either a single recordId or an array of recordIds as strings.
const extractRecordId = client =>
client
.find('Heroes', { name: 'yoda' })
.then(response => recordId(response.data))
.then(result => log('recordid-utility-example', result));
Excerpt from ./examples/utility.examples.js
Result:
[
"729068",
"729075",
"729078"
]
The fieldData method takes either an object or an array of objects and returns either a single object's fieldData or an array of fieldData objects.
const extractFieldData = client =>
client
.find('Heroes', { name: 'yoda' })
.then(response => fieldData(response.data))
.then(result => log('fielddata-utility-example', result));
Excerpt from ./examples/utility.examples.js
Result:
[
{
"id": "F3EE8445-8F11-8D42-B5B8-5442A1D91CF3",
"name": "Yoda",
"image(1)": "https://some-server.com/Streaming_SSL/MainDB/AEE712BE129B381ABC9F7B1AFA64F3D8B0A08E17A24AD91AAAE58B163FCEE4CB?RCType=EmbeddedRCFileProcessor",
"object": "",
"array": "",
"height": "",
"image(2)": "",
"recordId": "729068",
"modId": "1"
},
{
"id": "EE42F16D-1C92-CE47-91DF-C2BB6D8D9076",
"name": "Yoda",
"image(1)": "",
"object": "",
"array": "",
"height": "",
"image(2)": "",
"recordId": "729075",
"modId": "0"
},
{
"id": "BBAC1BA6-6346-654F-A787-E62BD8D0D0EA",
"name": "yoda",
"image(1)": "",
"object": "",
"array": "",
"height": "",
"image(2)": "",
"recordId": "729078",
"modId": "0"
}
]
npm install
npm test
> fms-api-client@1.4.5 test /Users/luidelaparra/Documents/Development/fms-api-client
> nyc _mocha --recursive ./tests --timeout=30000 --exit
Authentication Capabilities
✓ should authenticate into FileMaker. (614ms)
✓ should automatically request an authentication token (280ms)
✓ should reuse a saved authentication token (236ms)
✓ should log out of the filemaker. (304ms)
✓ should not attempt a logout if there is no valid token.
✓ should reject if the logout request fails (472ms)
✓ should reject if the authentication request fails (1484ms)
Create Capabilities
✓ should create FileMaker records. (219ms)
✓ should reject bad data with an error (3322ms)
✓ should create FileMaker records with mixed types (170ms)
✓ should substitute an empty object if data is not provided (801ms)
✓ should return an object with merged filemaker and data properties (252ms)
✓ should allow you to run a script when creating a record with a merge response (261ms)
✓ should allow you to specify scripts as an array (271ms)
✓ should allow you to specify scripts as an array with a merge response (191ms)
✓ should sanitize parameters when creating a new record (827ms)
✓ should accept both the default script parameters and a scripts array (216ms)
Delete Capabilities
✓ should delete FileMaker records. (266ms)
✓ should trigger scripts via an array when deleting records. (385ms)
✓ should trigger scripts via parameters when deleting records. (581ms)
✓ should allow you to mix script parameters and scripts array when deleting records. (331ms)
✓ should stringify script parameters. (306ms)
✓ should reject deletions that do not specify a recordId (173ms)
✓ should reject deletions that do not specify an invalid recordId (477ms)
Edit Capabilities
✓ should edit FileMaker records.
✓ should reject bad data with an error (379ms)
✓ should return an object with merged filemaker and data properties
✓ should allow you to run a script when editing a record (682ms)
✓ should allow you to run a script via a scripts array when editing a record (367ms)
✓ should allow you to specify scripts as an array (279ms)
✓ should allow you to specify scripts as an array with a merge response (226ms)
✓ should sanitize parameters when creating a new record (218ms)
✓ should accept both the default script parameters and a scripts array (229ms)
Find Capabilities
✓ should perform a find request (415ms)
✓ should allow you to use an object instead of an array for a find (243ms)
✓ should specify omit Criterea (350ms)
✓ should allow additional parameters to manipulate the results (3297ms)
✓ should allow you to limit the number of portal records to return (3269ms)
✓ should allow you to use numbers in the find query parameters (168ms)
✓ should allow you to sort the results (256ms)
✓ should return an empty array if the find does not return results (271ms)
✓ should allow you run a pre request script (3507ms)
✓ should return a response even if a script fails (311ms)
✓ should allow you to send a parameter to the pre request script (9552ms)
✓ should allow you run script after the find and before the sort (3229ms)
✓ should allow you to pass a parameter to a script after the find and before the sort (238ms)
✓ should reject of there is an issue with the find request (265ms)
Get Capabilities
✓ should get specific FileMaker records. (387ms)
✓ should reject get requests that do not specify a recordId (3373ms)
✓ should allow you to limit the number of portal records to return (370ms)
✓ should accept namespaced portal limit and offset parameters (6384ms)
Global Capabilities
✓ should allow you to set FileMaker globals (262ms)
✓ should reject with a message and code if it fails to set a global (221ms)
Request Interceptor Capabilities
✓ should reject if the server errors (133ms)
✓ should handle non JSON responses by rejecting with a json error (123ms)
✓ should reject non http requests to the server with a json error
*Notice* Data API response does not contain a code
✓ should reject non https requests to the server with a json error (3204ms)
List Capabilities
✓ should allow you to list records (3384ms)
✓ should allow you use parameters to modify the list response (4095ms)
✓ should should allow you to use numbers in parameters (177ms)
✓ should should allow you to provide an array of portals in parameters (793ms)
✓ should should remove non used properties from a portal object (3284ms)
✓ should modify requests to comply with DAPI name reservations (3593ms)
✓ should allow strings while complying with DAPI name reservations (307ms)
✓ should allow you to offset the list response (270ms)
✓ should santize parameters that would cause unexpected parameters (196ms)
✓ should allow you to limit the number of portal records to return (9449ms)
✓ should accept namespaced portal limit and offset parameters (269ms)
✓ should reject invalid parameters (203ms)
Script Capabilities
✓ should allow you to trigger a script in FileMaker (269ms)
✓ should allow you to trigger a script in FileMaker (527ms)
✓ should allow you to trigger a script in a find (315ms)
✓ should allow you to trigger a script in a list (3322ms)
✓ should allow reject a script that does not exist (3274ms)
✓ should allow return a result even if a script returns an error (278ms)
✓ should parse script results if the results are json (182ms)
✓ should not parse script results if the results are not json (183ms)
✓ should parse an array of scripts (576ms)
✓ should trigger scripts on all three script phases (238ms)
Storage
✓ should allow an instance to be created
✓ should allow an instance to be saved.
✓ should reject if a client can not be validated
✓ should allow an instance to be recalled
✓ should allow insances to be listed
✓ should allow you to remove an instance
File Upload Capabilities
✓ should allow you to upload a file to a new record (1622ms)
✓ should allow you to upload a file to a specific container repetition (1452ms)
✓ should reject with a message if it can not find the file to upload
✓ should allow you to upload a file to a specific record (1617ms)
✓ should allow you to upload a file to a specific record container repetition (4932ms)
✓ should reject of the request is invalid (442ms)
Data Usage
Tracks Data Usage
✓ should track API usage data. (9240ms)
✓ should allow you to reset usage data. (511ms)
Does Not Track Data Usage
✓ should not track data usage in (10162ms)
✓ should not track data usage out (258ms)
Utility Capabilities
✓ *Depricated* it should extract field while maintaining the array (644ms)
✓ *Depricated* it should extract field data while maintaining the object (385ms)
✓ *Depricated* it should extract the recordId while maintaining the array (3612ms)
✓ *Depricated* it should extract field data while maintaining the object (902ms)
✓ it should extract field while maintaining the array (401ms)
✓ it should extract field data while maintaining the object (614ms)
✓ it should extract the recordId while maintaining the array (349ms)
✓ it should extract field data while maintaining the object (607ms)
✓ it should remove properties while maintaing the array
✓ it should remove properties while maintaing the array
105 passing (2m)
------------------------------|----------|----------|----------|----------|-------------------|
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s |
------------------------------|----------|----------|----------|----------|-------------------|
All files | 100 | 100 | 100 | 100 | |
fms-api-client | 100 | 100 | 100 | 100 | |
index.js | 100 | 100 | 100 | 100 | |
fms-api-client/src | 100 | 100 | 100 | 100 | |
client.model.js | 100 | 100 | 100 | 100 | |
connection.model.js | 100 | 100 | 100 | 100 | |
credentials.model.js | 100 | 100 | 100 | 100 | |
data.model.js | 100 | 100 | 100 | 100 | |
index.js | 100 | 100 | 100 | 100 | |
request.service.js | 100 | 100 | 100 | 100 | |
fms-api-client/src/utilities | 100 | 100 | 100 | 100 | |
conversion.utilities.js | 100 | 100 | 100 | 100 | |
filemaker.utilities.js | 100 | 100 | 100 | 100 | |
index.js | 100 | 100 | 100 | 100 | |
------------------------------|----------|----------|----------|----------|-------------------|
MIT © Lui de la Parra
FAQs
A FileMaker Data API client designed to allow easier interaction with a FileMaker database from a web environment.
The npm package fms-api-client receives a total of 31 weekly downloads. As such, fms-api-client popularity was classified as not popular.
We found that fms-api-client 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 flawed sandbox in @nestjs/devtools-integration lets attackers run code on your machine via CSRF, leading to full Remote Code Execution (RCE).
Product
Customize license detection with Socket’s new license overlays: gain control, reduce noise, and handle edge cases with precision.
Product
Socket now supports Rust and Cargo, offering package search for all users and experimental SBOM generation for enterprise projects.