Skip to content

Commit

Permalink
Datamob sdk methods (#177)
Browse files Browse the repository at this point in the history
  • Loading branch information
atabel authored Dec 4, 2024
1 parent b0907db commit 399c945
Show file tree
Hide file tree
Showing 5 changed files with 278 additions and 1 deletion.
98 changes: 98 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1344,6 +1344,19 @@ await doExpensiveTask();
await hideLoadingOverlay();
```
#### Error cases
If `showLoadingOverlay` is called while the loading overlay is already being
shown, the promise will be rejected with an error object with the following
type:
```ts
{
code: 503;
description: 'Loading screen already showing';
}
```
### getInstallationId
<kbd>App version >=24.11</kbd>
Expand Down Expand Up @@ -1381,6 +1394,91 @@ app using the `setUnseenNotificationsBadge`. This way, the next time the webview
use the getter, it will know if the `lastUpdated` matches with the one persisted
in `localStorage`.
### requestDatamobDeviceAdmin
<kbd>App version >=25.x</kbd>
Datamob is a native library that offer developers a way to integrate security
and remote device control features into their applications.
The application that implements the Datamob library must be registered as a
system management application (Device Admin). This configuration is essential to
allow the application to have sufficient permissions to execute security
commands, such as screen lock and factory reset.
This method opens a setting screen asking the user to accept system management
permissions for the application.
```ts
requestDatamobDeviceAdmin: () => Promise<{isAdmin: boolean}>;
```
`isAdmin` is true if the permission was granted.
#### Demo
https://github.com/user-attachments/assets/28095f42-76db-4ac2-9586-e350acef7e1d
### registerDatamobUser
<kbd>App version >=25.x</kbd>
The application that implements the Datamob should have an user registered. This
method is used to register one.
```ts
registerDatamobUser: ({phoneNumber: string, tokenPassword: string}) => Promise<void>;
```
- `phoneNumber`: The phone number of the user.
- `tokenPassword`: When registering the device, datamob generate an accessKey
that is recorded in the Datamob device registry. By combining this attribute
with a hash that we keep in a password vault, generate this token.
#### Error cases
If the registration fails, the promise will be rejected with an error object
with the following type:
```ts
{
code: 500;
reason: `Registration error: ${errorDescription}`;
}
```
### validateDatamobRequirements
<kbd>App version >=25.x</kbd>
Datamob sdk allows to send remote commands to the user device. These remote
commands include actions such as locking the device screen (lock screen) or even
forcing a wipe (factory reset) of the device, providing additional security
control for the end user.
This method returns a map with the requirements. Each requirement is a boolean
value where true is valid, false is not valid.
```ts
validateDatamobRequirements: ({phoneNumber: string, tokenPassword: string}) => Promise<{
requirements: {
deviceAdmin: boolean;
googleAccount: boolean;
lockPassword: boolean;
accessibilityOption: boolean;
invalidPassword: boolean;
invalidToken: boolean;
}
}>
```
- `phoneNumber`: The phone number of the user.
- `tokenPassword`: When registering the device, datamob generate an accessKey
that is recorded in the Datamob device registry. By combining this attribute
with a hash that we keep in a password vault, generate this token.
- `requirements`: A map with the requirements.
## Error handling
If an uncontrolled error occurs, promise will be rejected with an error object:
Expand Down
6 changes: 6 additions & 0 deletions index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,3 +103,9 @@ export {
getUnseenNotificationsBadge,
setUnseenNotificationsBadge,
} from './src/inbox-notifications';

export {
registerDatamobUser,
requestDatamobDeviceAdmin,
validateDatamobRequirements,
} from './src/datamob';
106 changes: 106 additions & 0 deletions src/__tests__/datamob-test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import {
registerDatamobUser,
requestDatamobDeviceAdmin,
validateDatamobRequirements,
} from '../datamob';
import {createFakeAndroidPostMessage} from './fake-post-message';

test('requestDatamobDeviceAdmin', async () => {
createFakeAndroidPostMessage({
checkMessage: (msg) => {
expect(msg.type).toBe('REQUEST_DATAMOB_DEVICE_ADMIN');
},
getResponse: (msg) => ({
type: 'REQUEST_DATAMOB_DEVICE_ADMIN',
id: msg.id,
payload: {
isAdmin: true,
},
}),
});

const res = await requestDatamobDeviceAdmin();
expect(res).toEqual({isAdmin: true});
});

test('registerDatamobUser', async () => {
const phoneNumber = '666112233';
const tokenPassword = 'sometoken';
createFakeAndroidPostMessage({
checkMessage: (msg) => {
expect(msg.type).toBe('REGISTER_DATAMOB_USER');
expect(msg.payload).toEqual({phoneNumber, tokenPassword});
},
getResponse: (msg) => ({
type: 'REGISTER_DATAMOB_USER',
id: msg.id,
}),
});

const res = await registerDatamobUser({phoneNumber, tokenPassword});
expect(res).toBeUndefined();
});

test('registerDatamobUser error', async () => {
const phoneNumber = '666112233';
const tokenPassword = 'sometoken';
createFakeAndroidPostMessage({
checkMessage: (msg) => {
expect(msg.type).toBe('REGISTER_DATAMOB_USER');
expect(msg.payload).toEqual({phoneNumber, tokenPassword});
},
getResponse: (msg) => ({
type: 'ERROR',
id: msg.id,
payload: {
code: 500,
reason: 'Registration error',
},
}),
});

await expect(
registerDatamobUser({phoneNumber, tokenPassword}),
).rejects.toEqual({
code: 500,
reason: 'Registration error',
});
});

test('validateDatamobRequirements', async () => {
const phoneNumber = '666112233';
const tokenPassword = 'sometoken';
createFakeAndroidPostMessage({
checkMessage: (msg) => {
expect(msg.type).toBe('VALIDATE_DATAMOB_REQUIREMENTS');
expect(msg.payload).toEqual({phoneNumber, tokenPassword});
},
getResponse: (msg) => ({
type: 'VALIDATE_DATAMOB_REQUIREMENTS',
id: msg.id,
payload: {
requirements: {
deviceAdmin: true,
googleAccount: true,
lockPassword: true,
accessibilityOption: true,
invalidPhoneNumber: true,
invalidToken: true,
},
},
}),
});

const res = await validateDatamobRequirements({phoneNumber, tokenPassword});

expect(res).toEqual({
requirements: {
deviceAdmin: true,
googleAccount: true,
lockPassword: true,
accessibilityOption: true,
invalidPhoneNumber: true,
invalidToken: true,
},
});
});
40 changes: 40 additions & 0 deletions src/datamob.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import {postMessageToNativeApp} from './post-message';

export const requestDatamobDeviceAdmin = (): Promise<{isAdmin: boolean}> =>
postMessageToNativeApp({
type: 'REQUEST_DATAMOB_DEVICE_ADMIN',
payload: {},
}).then(({isAdmin}) => ({isAdmin}));

export const registerDatamobUser = ({
phoneNumber,
tokenPassword,
}: {
phoneNumber: string;
tokenPassword: string;
}): Promise<void> =>
postMessageToNativeApp({
type: 'REGISTER_DATAMOB_USER',
payload: {phoneNumber, tokenPassword},
});

export const validateDatamobRequirements = ({
phoneNumber,
tokenPassword,
}: {
phoneNumber: string;
tokenPassword: string;
}): Promise<{
requirements: {
deviceAdmin: boolean;
googleAccount: boolean;
lockPassword: boolean;
accessibilityOption: boolean;
invalidPhoneNumber: boolean;
invalidToken: boolean;
};
}> =>
postMessageToNativeApp({
type: 'VALIDATE_DATAMOB_REQUIREMENTS',
payload: {phoneNumber, tokenPassword},
}).then(({requirements}) => ({requirements}));
29 changes: 28 additions & 1 deletion src/post-message.ts
Original file line number Diff line number Diff line change
Expand Up @@ -379,13 +379,40 @@ export type ResponsesFromNativeApp = {
GET_UNSEEN_NOTIFICATIONS_BADGE: {
type: 'GET_UNSEEN_NOTIFICATIONS_BADGE';
id: string;
payload: {unseenNotificationCounter: number; lastUpdated: number};
payload: {
unseenNotificationCounter: number;
lastUpdated: number;
};
};
SET_UNSEEN_NOTIFICATIONS_BADGE: {
type: 'SET_UNSEEN_NOTIFICATIONS_BADGE';
id: string;
payload: void;
};
REQUEST_DATAMOB_DEVICE_ADMIN: {
type: 'REQUEST_DATAMOB_DEVICE_ADMIN';
id: string;
payload: {isAdmin: boolean};
};
REGISTER_DATAMOB_USER: {
type: 'REGISTER_DATAMOB_USER';
id: string;
payload: void;
};
VALIDATE_DATAMOB_REQUIREMENTS: {
type: 'VALIDATE_DATAMOB_REQUIREMENTS';
id: string;
payload: {
requirements: {
deviceAdmin: boolean;
googleAccount: boolean;
lockPassword: boolean;
accessibilityOption: boolean;
invalidPhoneNumber: boolean;
invalidToken: boolean;
};
};
};
};

export type NativeAppResponsePayload<
Expand Down

0 comments on commit 399c945

Please sign in to comment.