@mzaleski/use-send-code
v1.0.0
Published
A React (NextJS-oriented) hook that facilitates operations such as sending one-time codes.
Downloads
1
Maintainers
Readme
useSendCode
A React (NextJS-oriented) hook that facilitates operations such as sending one-time codes.
Table of Contents
Features
- Handle spam-sensitive operations such as one-time codes
- Session tracking through server-only cookie
- Session recovery on reload
- Component (button) props that handle every aspect of the user-facing CTA (label, disabled, loading, etc)
Motivation
Low-cost solution to spam-sensitive operations. This solution omits the use of a cache which might not always be available in early-stage applications.
Caveat
This solution was designed around the ability to retrieve server-only cookies with relative ease, e.g. NextJS' getServerSideProps
. A vanilla React application would not be suitable for this solution.
Installation
Install through your package manager of choice (npm, yarn, etc)
npm -i @mzaleski/use-send-code
yarn add @mzaleski/use-send-code
Usage
Example usage with NextJS' getServerSideProps
:
import { useSendCode } from '@mzaleski/use-send-code';
import { Button } from 'src/components';
async function worker(iamIdentifier: string): Promise<void> { ... }
function AccountRecoveryPage({ cookiePayload }) {
const { sendCode, status, buttonProps } = useSendCode(worker, {
iamIdentifier: 'some-id',
lastCodeIdentifier: cookiePayload?.iamIdentifier,
lastCodeSendAt: cookiePayload?.sentAt,
callOnMount: true,
cooldownPeriod: 2 * 60,
buttonPropsActiveLabel: 'Recover my account',
buttonPropsLoadingPropName: 'isLoading',
debugStatements: process.env.NODE_ENV === 'development',
sessionClearHandler: async () => { ... },
sessionPersistHandler: async (iamIdentifier) => { ... },
});
const sendRecoveryCode = async () => {
const err = await sendCode();
if (err) {
// handle error
}
};
return (
<Button {...buttonProps} onClick={sendRecoveryCode} />
);
}
export async function getServerSideProps(context) {
/** retrieve server-only cookie and deserialise it */
const cookiePayload = {...};
return {
props: {
cookiePayload,
},
};
}
Configuration
The hook's configuration is done through the opts
object which has the following properties:
| Name | Type | Description | Default |
| --- | --- | --- | --- |
iamIdentifier | String | The current user's unique identifier | [required] |
sessionClearHandler | Function | A function responsible for clearing the server-only cookie | [required] |
sessionPersistHandler | Function | - A function responsible for creating the server-only cookie; it is given the iamIdentifier
as parameter - The signature encourages the return of a server timestamp | [required] |
lastCodeIdentifier? | String | [retrieved from server-only cookie] the last code's iamIdentifier
| undefined
|
lastCodeSendAt? | String, Number | [retrieved from server-only cookie] when the last code was sent; it will be parsed by the Javascript Date
class. If the input is unparsable, the hook will throw InvalidLastCodeSentAtError
| undefined
|
callOnMount? | Boolean | Whether to call the worker on component mount | false
|
cooldownPeriod? | Number | The cooldown period in seconds | 300
(5 minutes) |
buttonPropsActiveLabel? | String | The button's label when a new code is available | "Send me a new code"
|
buttonPropsLoadingPropName? | String | [Custom component support] specify the loading
boolean property name on a custom button component | "loading"
|
debugStatements? | Boolean | Whether to log debug statements (requires development mode) | false
|
Properties
The hook returns an object with the following properties:
| Name | Type | Description |
| --- | --- | --- |
sendCode | Function | The function responsible for calling the worker and updating the internal state |
reset | Function | Will reset the hook to a "READY"
state; this same function is called once the cooldown has expired |
status | String | The current status of the hook; it can be one of the following: "READY"
, "COOLDOWN"
, "SENDING"
, "RESTORING"
|
buttonProps | Object | The props that should be passed to the button component; affected by buttonPropsActiveLabel
, buttonPropsLoadingPropName
|
Understanding the hook's behaviour
When a user clicks on the CTA
The hook will...
- Call your worker and perform the operation
- Call
sessionPersistHandler
with the giveniamIdentifier
to create a server-only cookie - Update its internal state as well the button's props in order to reflect the change
When the cooldown is active, but the user refreshes the page
The hook will restore the previous state by looking at lastCodeIdentifier
and lastCodeSendAt
from the server-only cookie.
When the cooldown period is over
The hook will...
- Call
sessionClearHandler
to clear the server-only cookie - Update its internal state as well the button's props in order to reflect the change
TypeScript Support
You will find a collection of typings bundled with the package.
License
MIT License (c) 2022 Maximilien Zaleski