Security News
Supply Chain Attack Detected in @solana/web3.js Library
A supply chain attack has been detected in versions 1.95.6 and 1.95.7 of the popular @solana/web3.js library.
hull-client
Advanced tools
Most low level Hull Platform API client:
const hull = new Hull({ configuration })
A bridge between Hull Client and a NodeJS HTTP application (e.g. express) which initializes context for every HTTP request:
app.use(Hull.Middleware({ configuration }))
A complete toolkit to operate with Hull Client in request handlers. Includes Hull Middleware and a set of official patterns to build highly scalable and efficient Connectors:
const connector = new Hull.Connector({ configuration })
This library makes it easy to interact with the Hull API, send tracking and properties and handle Server-side Events we send to installed Ships.
Creating a new Hull client is pretty straightforward:
npm install -s hull-client
import Hull from 'hull-client';
const client = new Hull({
id: 'HULL_ID',
secret: 'HULL_SECRET',
organization: 'HULL_ORGANIZATION_DOMAIN'
});
Once you have instantiated a client, you can use one of the get
, post
,
put
or delete
methods to perform actions of our APIs.
// client.api.get works too.
const params = {};
client.get(path, params).then(function(data) {
console.log(response);
}, function(err, response) {
console.log(err);
});
The first parameter is the route, the second is the set of parameters you want
to send with the request. They all return Promises so you can use the .then()
syntax if you're more inclined.
Every API client method get
, post
, put
and delete
accepts two options timeout
and retry
:
client.get(path, {}, {
timeout: 10000,
retry: 5000
});
Returns the global configuration object.
client.configuration();
// returns:
{ prefix: '/api/v1',
domain: 'hullapp.io',
protocol: 'https',
id: '58765f7de3aa14001999',
secret: '12347asc855041674dc961af50fc1',
organization: 'fa4321.hullapp.io',
version: '0.11.4' }
client.asUser({ email:'xxx@example.com', external_id: "1234", name:'FooBar' }).token(optionalClaims);
client.asAccount({ domain:'example.com', external_id: "1234", name:'FooBar' }).token(optionalClaims);
Used for Bring your own users.
Creates a signed string for the user passed in hash. userHash
needs an email
field.
You can then pass this client-side to Hull.js to authenticate users client-side and cross-domain
client.currentUserId(userId, userSig)
Checks the validity of the signature relatively to a user id
One of the more frequent use case is to perform API calls with the identity of a given user. We provide several methods to do so.
// if you have a user id from your database, use the `external_id` field
const user = client.asUser({ external_id: "dkjf565wd654e" });
// if you have a Hull Internal User Id:
const user = client.asUser({ id: "5718b59b7a85ebf20e000169" });
// or just as a string:
const user = client.asUser("5718b59b7a85ebf20e000169");
// you can optionally pass additional user resolution options as a second argument:
const user = client.asUser({ id: "5718b59b7a85ebf20e000169" }, { create: false });
// Constant `user` is an instance of Hull, scoped to a specific user.
user.get("/me").then(function(me) {
console.log(me);
});
user.userToken();
You can use an internal Hull id
, an ID from your database that we call external_id
, an email
address or anonymous_id
.
Assigning the user
variable doesn't make an API call, it
the calls to another instance of hull
client. This means user
is an instance of the hull
client scoped to this user.
The second parameter lets you define additional options (JWT claims) passed to the user resolution script:
Return a hull
client
scoped to the user identified by it's Hull ID. Not lazily created. Needs an existing User
client.asUser(userId);
Return a hull
client
scoped to the user identified by it's Social network ID. Lazily created if Guest Users are enabled
client.asUser('instagram|facebook|google:userId');
Return a hull
client
scoped to the user identified by it's External ID (from your dashboard). Lazily created if Guest Users are enabled
client.asUser({ external_id: 'externalId' });
Return a hull
client
scoped to the user identified by it's External ID (from your dashboard). Lazily created if Guest Users are enabled
client.asUser({ anonymous_id: 'anonymousId' });
Return a hull
client
scoped to the user identified by only by an anonymousId. Lets you start tracking and storing properties from a user before you have a UserID ready for him. Lazily created if Guest Users are enabled When you have a UserId, just pass both to link them.
client.asUser({ email: "user@email.com" });
Return a hull
client
authenticated as the user but with admin privileges
client.asUser({ email: 'user@email.com' }, { scopes: ['admin'] });
const externalId = "dkjf565wd654e";
const anonymousId = "44564-EJVWE-1CE56SE-SDVE879VW8D4";
const user = client.asUser({ external_id: externalId, anonymous_id: anonymousId });
When you do this, you get a new client that has a different behaviour. It's now behaving as a User would. It means it does API calls as a user and has new methods to track and store properties
Stores a new event.
user.track('new support ticket', { messages: 3,
priority:'high'
}, {
source: 'zendesk',
type: 'ticket',
event_id: 'uuid1234' //Pass a unique ID to ensure event de-duplication
ip: null, //don't store ip - it's a server call
referer: null, //don't store referer - it's a server call
created_at: '2013-02-08 09:30:26.123+07:00' //ISO 8601. moment.js does it very well
});
The context
object lets you define event meta-data. Everything is optional
zendesk
, mailchimp
, stripe
mail
, ticket
, payment
now()
event_id
, they will overwrite the previous one.null
if you're storing a server call, otherwise, geoIP will locate this event.null
for server calls.Stores Attributes on the user:
user.traits({
opened_tickets: 12
}, { source: 'zendesk' });
// 'source' is optional. Will store the traits grouped under the source name.
// Alternatively, you can send properties for multiple groups with the flat syntax:
user.traits({ "zendesk/opened_tickets": 12, "clearbit/name": "foo" });
By default the traits
calls are grouped in background and send to the Hull API in batches, that will cause some small delay. If you need to be sure the properties are set immediately on the user, you can use the context param { sync: true }
.
user.traits({
fetched_at: new Date().toISOString()
}, {
source: 'mailchimp',
sync: true
});
The Hull API returns traits in a "flat" format, with '/' delimiters in the key.
client.utils.traits.group(user_report)
can be used to group those traits into subobjects:
client.utils.traits.group({
'email': 'romain@user',
'name': 'name',
'traits_coconut_name': 'coconut',
'traits_coconut_size': 'large',
'traits_cb/twitter_bio': 'parisian',
'traits_cb/twitter_name': 'parisian',
'traits_group/name': 'groupname',
'traits_zendesk/open_tickets': 18
});
// returns
{
'id' : '31628736813n1283',
'email': 'romain@user',
'name': 'name',
'traits': {
'coconut_name': 'coconut',
'coconut_size': 'large'
},
cb: {
'twitter_bio': 'parisian',
'twitter_name': 'parisian'
},
group: {
'name': 'groupname',
},
zendesk: {
'open_tickets': 18
}
};
This utility can be also used in following way:
const client = new Hull({ config });
const userGroupedTraits = client.utils.traits.group(user_report);
The Logger comes in two flavors, Hull.logger.xxx
and hull.logger.xxx
- The first one is a generic logger, the second one injects the current instance of Hull
so you can retreive ship name, id and organization for more precision.
Uses Winston
Hull.logger.info("message", { object }); //Class logging method,
client.logger.info("message", { object }); //Instance logging method, adds Ship ID and Organization to Context. Use if available.
//Debug works the same way but only logs if process.env.DEBUG===true
Hull.logger.info("message", { object }); //Class logging method,
client.logger.info("message", { object });
//You can add more logging destinations like this:
import winstonSlacker from "winston-slacker";
Hull.logger.add(winstonSlacker, { ... });
You can also have a user or account scoped logger. Claims used in asUser
and asAccount
methods will be added to the log context.
const user = client.asUser({ email: "john@coltrane.com" });
user.logger.info("message", { hello: "world" });
hostSecret
The ship hosted secret - consider this as a private key which is used to encrypt and decrypt
req.hull.token
. The token is useful for exposing it outside the Connector <-> Hull Platform communication. For example the OAuth flow or webhooks. Thanks to the encryption no 3rd party will get access to Hull Platform credentials.
clientConfig
Additional config which will be passed to the new instance of Hull Client
1.1.3
FAQs
A barebones Node.js API client for hull.io
The npm package hull-client receives a total of 278 weekly downloads. As such, hull-client popularity was classified as not popular.
We found that hull-client demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 3 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.
Security News
A supply chain attack has been detected in versions 1.95.6 and 1.95.7 of the popular @solana/web3.js library.
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.