snowtools-session-context v1.0.3
snowtools-session-context
This React-Native library provides session context to your application. Upon authentication, a session token is issued and stored securely on the device. Your page logic can therefore inspect the session details to determine if someone is logged in and fetch their basic details. All API calls and WebSocket connections will automatically provide the session token as the AuthN strategy.
Installing
npm i snowtools-session-context
Declaring
The SessionContextProvider needs to be top-most element, so that anything underneath can access and make use of the Session Context provider.
import { SessionContextProvider } from "snowtools-session-context";
export default function Index() {
return (
<SessionContextProvider>
<!-- your content goes here -->
</SessionContextProvider>
);
}
Usage
Inside your component functions that are declared wihtin the scope of the SessionContextProvider
, you can make use of the Session Context by declaring the methods you wish to use:
import { useSessionContext } from "snowtools-session-context";
export default function MyComponent() {
const { services, session, isOnline, isBiometricAuthenticated, isBiometricAuthenticatedOnce } = useSessionContext();
}
Methods Available
Name | Returns | Description |
---|---|---|
services | Services | Useful service methods (see Service Methods below) |
session | Session | Returns the session context if the user is logged in or null if not |
isOnline | boolean | Whether we have an active WebSocket to the application server |
isBiometricAuthenticated | boolean | Has the user been authenticated by biometics in the past n seconds |
isBiometricAuthenticatedOnce | boolean | Has the user been authenticated by biometics since opening the app |
Service Methods
Method | Description |
---|---|
callApi(params: ApiWrapperParams): Promise; | Make a JSON request/response to the application server (see Calling APIs below) |
isLoading(): boolean; | Returns true when an API call is in progress. Useful for toggling UI functionality (see Calling APIs below) |
goOnline(): void; | Open the WebSocket connection to the application server (see Using WebSockets below) |
goOffline(): void; | Close the WebSocket connection to the application server (see Using WebSockets below) |
sendMessage(message: string): void; | Send a message over the WebSocket to the application server (see Using WebSockets below) |
registerListener(name: string, callback: SetStateAction): void; | Register a recipient of response messages from the application server via WebSocket (see Using WebSockets below) |
isBiometricAuthenticated(timeout?: number): boolean; | Check if the user has been authenticated biometricly since timeout seconds ago |
authenticateBiometric(timeout?: number): Promise; | Authenticate the user using biometrics if they haven't been autenticated since timeout seconds ago (or immediately if timeout is undefined ) |
Calling APIs
Define globally the base URL to use for API calls:
import { serviceDefaults } from "snowtools-session-context";
serviceDefaults.setBaseUrl("https://localhost/myapiservices");
The follow example shows a HTTP POST of credentials to the "/login" service:
const [userEnteredEmail, setUserEnteredEmail] = useState<string | null>(null);
const [userEnteredPassword, setUserEnteredPassword] = useState<string | null>(null);
...
services
.callApi({
url: "/login",
body: {
email: userEnteredEmail,
password: userEnteredPassword,
},
})
.then((response) => {
if (response.err) Alert.alert(response.msg);
// If all went well, then `callApi` did the setSession call
})
.catch((error) => {
Alert.alert("Login Error", "Unknown Error");
console.log(error);
});
If url
starts with /
, then the default URL prefix will be used, which goes to the application server. To call an API outside of the application server, then put the full URL in url
, for example: http://somewhere.com/api
.
JSON Response Structure
Either the resposne will be what the caller expects, or it will contain the following attributes:
{
"err": boolean,
"msg": string,
"session": Session
}
Session contains the following:
{
"fn": string,
"ln": string,
"loc": string,
"token": JWT,
"sid": uuid,
"uid": uuid
}
Name | Description |
---|---|
fn | First name |
ln | Last name |
loc | Locale (eg: en-US) |
token | JWT used for subsequent API calls and for creating a WebSocket connection |
sid | UUID of the user's current login session |
uid | UUID of the user |
Using WebSockets
Define globally the base URL to use for API calls:
import { serviceDefaults } from "snowtools-session-context";
serviceDefaults.setBaseWebsocketUrl("https://localhost/mywebsocketapp");
The follow example shows a HTTP POST of credentials to the "/login" service:
The following test component will automatically initiate a WebSocket using services.goOnline()
and register the myclientservice
recipient as a call to the setOutputText(string)
function. There is an online/offline status bar (green/red respectively) that uses the isOnline
flag. Finally messages are sent to the websocket using the services.sendMessage(message)
function.
import { View, Text, StyleSheet, Button } from "react-native";
import { useSessionContext } from "snowtools-session-context";
import { TextInput } from "react-native";
import { useState } from "react";
function MyWebSocketTestComponent({ navigation }: { navigation: any }) {
const { services, session, setSession, isOnline } = useSessionContext();
const [inputText, setInputText] = useState();
const [outputText, setOutputText] = useState();
services.goOnline();
services.registerListener("myclientservice", setOutputText);
return (
<>
{isOnline && (
<View style={{ backgroundColor: "green" }}>
<Text>Online!</Text>
</View>
)}
{!isOnline && (
<View style={{ backgroundColor: "red" }}>
<Text>Offline</Text>
</View>
)}
<View style={styles.container}>
<TextInput
placeholder="Test"
autoCorrect={false}
autoCapitalize="none"
value={inputText}
onChangeText={setInputText}
/>
<Text>Result: {outputText}</Text>
<Button
title="Test WebSocket"
onPress={() => {
services.sendMessage(
'{"from": "myclientservice", "data": "sending ' + inputText + '"}'
);
}}
/>
</View>
</>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
flexDirection: "column",
justifyContent: "center",
alignItems: "center",
backgroundColor: "#ccc",
},
});
Using Localisations
It is best to feed your local translations into the Session Context Localisation as it will be switched automatically when the locale in user's context changes. To add your own translation files, do the following globally:
import { i18n } from "snowtools-session-context";
import en from "@/assets/languages/en";
import fr from "@/assets/languages/fr";
i18n.store({
en: en,
fr: fr,
});
You can still override the locale manually if needed:
i18n.locale = "en";