Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Datamob sdk methods #177

Merged
merged 9 commits into from
Dec 4, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 75 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1372,6 +1372,81 @@ 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 >=24.12</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 >=24.12</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<{success: 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.

- `success`: true if the user was registered successfully.

### validateDatamobRequirements

<kbd>App version >=24.12</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;
atabel marked this conversation as resolved.
Show resolved Hide resolved
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
83 changes: 83 additions & 0 deletions src/__tests__/datamob-test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
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,
payload: {
success: true,
},
}),
});

const res = await registerDatamobUser({phoneNumber, tokenPassword});
expect(res).toEqual({success: true});
});

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,
invalidPassword: true,
invalidToken: true,
},
},
}),
});

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

expect(res).toEqual({
requirements: {
deviceAdmin: true,
googleAccount: true,
lockPassword: true,
accessibilityOption: true,
invalidPassword: 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<{success: boolean}> =>
postMessageToNativeApp({
type: 'REGISTER_DATAMOB_USER',
payload: {phoneNumber, tokenPassword},
}).then(({success}) => ({success}));

export const validateDatamobRequirements = ({
phoneNumber,
tokenPassword,
}: {
phoneNumber: string;
tokenPassword: string;
}): Promise<{
requirements: {
deviceAdmin: boolean;
googleAccount: boolean;
lockPassword: boolean;
accessibilityOption: boolean;
invalidPassword: 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: {success: boolean};
};
VALIDATE_DATAMOB_REQUIREMENTS: {
type: 'VALIDATE_DATAMOB_REQUIREMENTS';
id: string;
payload: {
requirements: {
deviceAdmin: boolean;
googleAccount: boolean;
lockPassword: boolean;
accessibilityOption: boolean;
invalidPassword: boolean;
invalidToken: boolean;
};
};
};
};

export type NativeAppResponsePayload<
Expand Down