All error responses from our API will include a message key.
Error response from our API. err
will contain an ApiError
,
while data
will be null
.
All possible options which can be fed into our shared response generator functions.
Manually set an error code according to the situation.
Will yield a 201
error code, following HTTP spec
If set & item was not found, will yield a proper
404
error code.
Successful response from our API. data
will contain the
corresponding Result
, err
will be null.
General shape which all responses from our API conform to.
An object res
where either res.data
or res.err
won't
be null
, depending on whether your call succeeded.
Both will always be defined. Note that this just describes
the body of the response. If there's an error, the error
code will also be set to 4xx or 5xx, so your request
tool will automatically detect there's an error.
Basic response which simply contains a message about the action that was taken.
Basic result which simply contains a message about the action that was taken.
Type guard; only returns true
if object shape has a null
data
value and a non-null err
value.
HttpMethods type is a union of string literals, rather than an enum, because these literals will not change over time. Enums make it easy to change values in the future, like if we restructure our API. For values which are an unchanging constants, simply specifying string literals still gives us the guarantee of no typos. It also means that we can satisfy the type by writing 'POST', rather than HttpMethods.POST.
Type guard; only returns true
if res
has a
message
key holding a string
value.
Type guard; only returns true
if object shape has a non-null
data
value and err
has a null value.
Factory function which accepts a string to produce a new message result.
Generalized function which uses the provided body
to
build a response object; prefer to instead use the more
specific functions which will correctly set options for
you.
Depending on whether opts
say it's an error, the final
response body will either have res.data = JSON.stringify(body)
or res.err = JSON.stringify(body)
. The other property
will always be null. In the case of isErr
without a
more specific error code, return code is 500
.
Helper response function; correctly builds our response object
for a successful 200
response. body
will become the value in
res.data
, res.err
will be null
.
Given an object which is known to be the wrong shape, along with an object of the correct shape, this function iterates over every key on the correct object and includes an error message if that key is missing or of incorrect type on the wrong object.
Helper response function; correctly builds our response object
in the case of some internal error. If a method we don't expect
to throw an error suddenly does, then we should return this
unexpectedErrorResponse()
. This sets the return code to 500
,
which means "Internal Server Error".
Helper response function; correctly builds our response object
in the case of a user error. This would include things like
requests with invalid bodies. It sets the return code to 400
,
which means "Bad Request". res.data
will be null
, and
res.err
will be this body
.
Convenient type which takes an interface and
produces a type like
type DappUpdate = AtLeastOne<Dapp.Item.Core>
Taken from @jcalz on StackOverflow: https://stackoverflow.com/a/48244432/2128308
Type guard; returns true
if maybe
is a boolean,
false
otherwise.
Unofficial type guard, returns true if
typeof maybe === 'object'
, false otherwise.
Does not declare itself as enforcing type
'object'
because then TS thinks the output
can't have any other properties.
Type guard; returns true
if maybe
is a string,
false
otherwise.
Helper validation function which checks whether
all propertyNames
are present on body
and
then checks that their values are booleans.
Helper validation function which checks whether
all propertyNames
are present on body
and
then checks that their values are strings.
Helper validation function; provide an object and a list of string keys, returns true if all are present & not null.
Very flexible validation function which accepts
an object to check, properties to inspect, and a
test function to see if the value is correct.
Only returns true
if isVal(body.prop)
returns
true
for every prop in propertyNames
.
All of the potential shapes for a DappItem at different points throughout our system, along with factory functions and type guards.
Dapp representation returned from private reads and lists, includes everything from full plus some dapp management data.
All data required to render a dapp on DappHub; this is the dapp's shape when returned from the public view.
Core data plus the dapp's tier and some optional info about the GitHub integration. This type applies to both enterprise and standard dapps.
Type guard; returns true
if the argument
satisfies Item.Api
, otherwise false
.
Type guard; returns true
if the argument
satisfies Item.Core
, otherwise false
.
Type guard; returns true
if the argument
satisfies Item.Full
, otherwise false
.
Factory to produce an empty Item.Api
.
Useful to get the interface's keys as
a value. Note that the actual values on
this object are not valid.
Factory to produce an empty Item.Core
.
Useful to get the interface's keys as
a value. Note that the actual values on
this object are not valid.
Factory to produce an empty Item.Full
.
Useful to get the interface's keys as
a value. Note that the actual values on
this object are not valid. It produces
a standard dapp, so no GitHub config.
All possible values for the State of a Dapp as formatted from the API.
Possible Dapp tiers and their string name representations.
Given a potential DappName, applies a regex which outputs a valid DappName.
Type guard; only valid enum values within the
States enum will return true
.
Type guard; only valid enum values within the
Tiers enum will return true
.
Initiate a password reset. This call will trigger an email containing the passwordResetCode which must be provided to confirm the reset.
When successful, the message ought to say something like, "An email has been sent with a temporary password."
Type guard; only returns true for valid Args
objects.
Factory to produce an Args object with empty strings. Useful for getting the correct shape as a value.
Begin Setup for App MFA
Returns secret code to enter into the MFA App.
Type guard; only returns true for valid Args
objects.
Factory to produce an Args object with empty strings. Useful for getting the correct shape as a value.
Conclude a password reset by supplying the code from the email along with a new password.
Ought to tell them they can now log in with their new password.
Type guard; only returns true for valid Args
objects.
Factory to produce an Args object with empty strings. Useful for getting the correct shape as a value.
Confirm Setup for App MFA
When successful, the message ought to say something like, "Your MFA app has been successfully configured."
Type guard; only returns true for valid Args
objects.
Factory to produce an Args object with empty strings. Useful for getting the correct shape as a value.
Main login call which either produces a user object and credentials, or returns a challenge.
Type guard; only returns true for valid Args
objects.
Factory to produce an Args object with empty strings. Useful for getting the correct shape as a value.
Corresponds to the challenge a user with MFA enabled gets to verify their MFA code.
Note that the session here would be from a previous ChallengeResponse. This is not the Authorization token, these values are passed back and forth in each step of a Challenge Response interaction.
Type guard; only returns true for valid Args
objects.
Factory to produce an Args object with empty strings. Useful for getting the correct shape as a value.
Corresponds to the initial challenge a user receives after making their account so they can create a new one.
Note that the session here would be from a previous ChallengeResponse. This is not the Authorization token, these values are passed back and forth in each step of a Challenge Response interaction.
Type guard; only returns true for valid Args
objects.
Factory to produce an Args object with empty strings. Useful for getting the correct shape as a value.
Refresh login call which only requires a token and ought to produce fresh credentials, unless it has been more than a month.
Type guard; only returns true for valid Args
objects.
Factory to produce an Args object with empty strings. Useful for getting the correct shape as a value.
Corresponds to the challenge a user with MFA enabled gets to verify their MFA code.
Note that the session here would be from a previous ChallengeResponse. This is not the Authorization token, these values are passed back and forth in each step of a Challenge Response interaction.
Type guard; only returns true for valid Args
objects.
Factory to produce an Args object with empty strings. Useful for getting the correct shape as a value.
Sets user MFA preferences
Returns which MFA method (if any) is enabled
Type guard; only returns true for valid Args
objects.
Factory to produce an Args object with empty strings. Useful for getting the correct shape as a value.
Setup Phone Number for SMS MFA
Phone numbers must follow these formatting rules: A phone number must start with a plus (+) sign, followed immediately by the country code. A phone number can only contain the + sign and digits. You must remove any other characters from a phone number, such as parentheses, spaces, or dashes (-) before submitting the value to the service. For example, a United States-based phone number must follow this format: +14325551212. (Sourced from: https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-settings-attributes.html)
When successful, the message ought to say something like, "Your phone number has been registered for SMS MFA."
Type guard; only returns true for valid Args
objects.
Factory to produce an Args object with empty strings. Useful for getting the correct shape as a value.
Subpaths available on the auth endpoint. Built into an enum for easy change later on.
Decoded API response from a call to our login endpoint. It either contains successful authentication ora challenge for the user to respond to.
Response from a call to our login endpoint. It either contains successful authentication or a challenge for the user to respond to.
Baseline path from which more specific auth paths are built on top of.
Cancel a given user's subscription to DappBot. This will immediately delete all the customer's dapps, zero out their dapp limits, cancel the subscription on Stripe, and leave the user in the CANCELLED state.
No body arguments required, user's email is inferred from Authorization token.
Retrieve a given user's Stripe details, specifically their customer, subscription, and an invoice. If they're lapsed, then it's the most recent failed invoice. If they're active, it's the upcoming invoice. For all Stripe details, if this user does not have Stripe, they will be null.
Body has no args, customer email is read via the Authorization token.
Main method to create a new account. If called as an API customer, you can only create a trial account. Card info can only ever be plugged in through the DappBot web interface.
The token here is produced by Stripe on dapp.bot and cannot be created by external API customers. If it is not provided, then the new account is automatically created with a two-week free trial that allows one standard dapp.
Type guard; only returns true for valid Args objects.
Factory to produce an Args object with empty strings for auth and a trial stripe plan. Useful for getting the correct shape as a value.
The subset of Stripe's types which we use, extracted into a convenient namespace. For more info about how the underlying objects look, check the official Stripe documentation -- it's excellent.
Array of subscription states which translate to an active payment status for the underlying user.
Used to update the customer's saved payment source, currently a credit card.
Like with SignUp, this token can only be produced on the dapp.bot website using Stripe's client-side plugin. This method cannot be successfully called by external API customers.
Type guard; only returns true
for valid Args
objects.
Factory to produce an Args object with an empty string. Useful for getting the correct shape as a value, without having to hardcode strings.
Update the number of allowed dapps for each type. This method can only be called by active accounts with a working payment source. Your account's next invoice will be prorated to reflect the updated capacity.
Type guard; only returns true for valid Args
objects.
Factory to produce an Args object with one standard dapp. Useful for getting the correct shape as a value, without having to hardcode strings.
Listing of how many dapps a customer has allowed for each tier. Note that all must be specified, including 0 values, for safety.
Factory to get a Stripe plan config that has ten standard dapps, the value allowed on free tier.
Type guard; only returns true for
valid StripePlans
objects.
Create a new dapp. Accepts all properties from a full DappItem, except for the name, which the API infers by the path.
Message ought to be something like, "Your dapp has been successfully created."
Given a DappName, return the fully scoped private path to create it.
Type guard; only returns true
if all Item.Full
attributes other than DappName
have been
correctly set. The underlying guard verifies
that if it's an Enterprise Dapp, the GitHub
config is set.
Factory to produce an Args object with an empty string. Useful for getting the correct shape as a value, without having to hardcode strings.
Delete an existing dapp. Its DappName will be reclaimed for other users. Only works if the caller is the dapp's owner.
Body requires no arguments, email and DappName are taken from Authorization & path respectively.
Message will say something (not exactly) like, "Your dapp has been successfully deleted."
Given a DappName, returns its fully scoped private path
List all of the dapp's owned by the calling user in their API representation.
Body requires no arguments, email and DappName are taken from Authorization & path respectively.
Retrieve the API representation of any given
dapp. Will not succeed if the caller is not
the owner of said dapp. Gracefully returns
with itemExists === false
if the dapp does
not exist.
Body requires no arguments, email and DappName are taken from Authorization & path respectively.
Given a DappName, returns its fully scoped private path
Update an existing dapp. An existing Dapp can only have its ABI, ContractAddr, Web3URL, & GuardianURL modified. Only works if the caller is the dapp's owner.
Message will say something (not exactly) like, "Your dapp has been successfully updated."
Given a DappName, returns its fully scoped path
Type guard; only returns true
if one of the
valid Item.Core
update attributes has been set.
Factory to produce a sample Args object. As the argument only requires one to be set, this arg would set the Web3URL to a blank string.
Retrieve the publicly visible information about a Dapp, or put differently, the content required for it to render on DappHub.
No body required, DappName is taken from the path.
Given a DappName, returns its fully scoped public path
When a user logs in with their username & password, they may have to respond to a challenge in order to finish the auth loop. This is a collection of data types and helper functions related those ChallengeResponse interactions.
Our internal key of possible challenges from
Cognito. ForgotPassword
and Default
are
constants we made up to control the client-side
interface -- the former means we've begun a
PassReset
flow, the latter means there is
no challenge at all. NewPasswordRequired
and
MFA-related challenges, however, are proper
Cognito challenges. You can view the whole
list of them at:
General response shape for all Challenges. They
will always have a ChallengeName
, and the
Session
key is a special value which must be
passed back and forth throughout the Challenge-Response
flow.
Type guard; only returns true
if maybe
fully
satisfies Challenges.Data
. Validates that the
name is a valid value from Challenges.Types
,
that the session is a string, and that
Data.ChallengeParameters
has only string keys &
string values.
Type guard; only valid values for the
MfaTypes type will return true
.
Type guard; only valid enum values within the
Types enum will return true
.
Factory function to produce an empty ChallengeData
object. Session
is an empty string, the name is
Types.Default
, and ChallengeParameters
is an
empty object.
Collection of helper types describing attributes
on a Cognito user. UserAttributes
technically
comes out of Cognito as a ListType
, but we
transform it on the server into a MapType
which
fits the UserAttributes
spec.
All possible custom:payment_provider
s for a DappBot
user. As of Fall 2019, the only options are they're
paying with Stripe or they have an admin account.
All possible custom:payment_status
es for a DappBot
user. If all is well, they're ACTIVE
. Once a
payment fails, they're LAPSED
. If it stays failed,
the user eventually goes into FAILED
. Their status
will only be CANCELLED
once they explicitly zero
out their subscripton.
Object returned after successful login to DappBot.
Authorization
is the exact token which should go
into the Authorization
header (no Bearer
).
RefreshToken is used to get new Authorization
after it expires at ExpiresAt
, which is a date
encoded as an ISO string.
UserAttributes map including all of the custom
properties we added to the Cognito user. The
limit
attributes all control how many dapps
the user is allowed to make, payment_provider
says whether they are using Stripe,
payment_status
says whether their payments
are all up to date.
DappBot User Record as defined by Cognito. This interface basically follows the default Cognito user, but we have enforced additional constraints on UserAttributes, which is otherwise an arbitrary set of key-val string pairs.
Given valid AuthData, return an object stating whether the data is active (authorized), stale (needs refresh), or empty (needs full login).
Type guard; only returns true
if maybe
fully
satisfies the AuthData
interface. Leverages
isUserData
to check AuthData.User
. Checks that
ExpiresAt
is a valid ISO string, just checks the
other two props are strings.
Validates that the enum values within UserAttributes
are actually from the appropriate enums, validates
that the limit values can be converted to non-negative
integers.
Type guard; only returns true if maybe
satisfies
the UserData
interface. Recursively verifies that
maybe.UserAttributes
verifies the UserAttributes
interface.
Factory which produces an empty AuthData object.
Leverages emptyUserData()
for User
key,
ExpiresAt
is now as an ISO string, Authorization
& RefreshToken
are empty strings.
Factory to produce a blank UserAttributes object. For validity, it is configured as an active admin account with one standard dapp. These factories are convenient for getting blank objects of the correct type, or a list of the interface's keys as a value.
Factory to produce an empty UserData object. All string values are empty except for the UserAttributes, which simulate an admin account that is only allowed to make one standard dapp. These factories are convenient for getting blank objects or a list of the interface's keys as a value.
Validator function which returns true
if the
provided string has a length from 8-64 chars,
has upper & lowercase characters, no whitespace,
and a symbol. Otherwise returns false
.
Generated using TypeDoc
Namespace containing types for the key HTTP verbs. Each verb has a dedicated string literal type, and then
HttpMethods.ANY
allows any of those values.