pushwave-client 0.2.4 → 0.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +94 -0
- package/dist/registerPushWave.d.ts +2 -1
- package/dist/registerPushWave.js +2 -1
- package/dist/utils/fetch.js +1 -0
- package/package.json +1 -1
- package/src/attestation/attestation.types.ts +30 -0
- package/src/attestation/getApplicationAttestation.ts +2 -32
- package/src/attestation/index.ts +2 -0
- package/src/index.ts +1 -4
- package/src/register/index.ts +2 -0
- package/src/register/registerPushWave.dto.ts +16 -0
- package/src/{registerPushWave.ts → register/registerPushWave.ts} +8 -24
- package/src/utils/fetch.ts +2 -0
- package/src/utils/validation.ts +0 -0
package/README.md
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# pushwave-client (alpha)
|
|
2
|
+
|
|
3
|
+
Expo/React Native SDK for the upcoming PushWave SaaS (work in progress). Goal: fetch the Expo push token and prepare app attestation (Android Play Integrity / iOS DeviceCheck) to secure notification delivery. The SaaS/backend validation is coming soon—consider this an early-stage project.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Quick install
|
|
8
|
+
|
|
9
|
+
1) Install the [SDK](https://www.npmjs.com/package/pushwave-client) and [Expo notifications](https://docs.expo.dev/versions/latest/sdk/notifications/) (peer requirement):
|
|
10
|
+
```bash
|
|
11
|
+
npm install pushwave-client
|
|
12
|
+
npx expo install expo-notifications
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
2) Add the config plugin to your app.json / app.config.*:
|
|
16
|
+
```json
|
|
17
|
+
{
|
|
18
|
+
"expo": {
|
|
19
|
+
"plugins": ["pushwave-client"]
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
3) Build native (EAS or dev client). Expo Go is not supported once native code is involved:
|
|
25
|
+
```bash
|
|
26
|
+
eas build -p android --profile development
|
|
27
|
+
eas build -p ios --profile development
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## Minimal usage
|
|
33
|
+
|
|
34
|
+
```tsx
|
|
35
|
+
import { useEffect } from "react";
|
|
36
|
+
import { Alert } from "react-native";
|
|
37
|
+
import PushWaveClient from "pushwave-client";
|
|
38
|
+
|
|
39
|
+
export default function App() {
|
|
40
|
+
useEffect(() => {
|
|
41
|
+
(async () => {
|
|
42
|
+
const res = await PushWaveClient.init({ apiKey: "pw_dev_xxx" });
|
|
43
|
+
if (!res.success) {
|
|
44
|
+
Alert.alert("PushWave", res.message ?? "Init failed");
|
|
45
|
+
}
|
|
46
|
+
})();
|
|
47
|
+
}, []);
|
|
48
|
+
|
|
49
|
+
return /* …your UI… */;
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
- `PushWaveClient.init` is async and returns `{ success: boolean; message?: string }`.
|
|
54
|
+
- Call it **once** at app startup (e.g., in `App.tsx` or a root component `useEffect`). Recalling it later is unnecessary.
|
|
55
|
+
- In `__DEV__`, the SDK may log additional info/errors (e.g., failed API calls) to help debugging.
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## Notifications (expo-notifications)
|
|
60
|
+
|
|
61
|
+
- The SDK retrieves the user’s Expo push token. If the user denies notification permission, no push will be delivered and the token may not be available depending on platform/permission.
|
|
62
|
+
- On iOS, user permission is required to obtain a push token.
|
|
63
|
+
- On Android, Expo handles permission/channel setup; if the user refuses, no push is delivered.
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## Attestation (current status)
|
|
68
|
+
|
|
69
|
+
- Backend validation is not live yet; it will arrive with the PushWave SaaS.
|
|
70
|
+
- Android (Play Integrity): will require a build distributed via the Play Store (internal/closed track) with Play App Signing + Play Integrity API enabled. No support for Expo Go / sideload.
|
|
71
|
+
- iOS (DeviceCheck): will require a real build (dev client or TestFlight), not Expo Go.
|
|
72
|
+
- For now, consider attestation non-blocking (the SDK may return a `disabled` flag until the SaaS is active).
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
## Compatibility
|
|
77
|
+
|
|
78
|
+
- Tested on the latest Expo SDK (54). No guarantees on earlier versions.
|
|
79
|
+
- Requires a native build (EAS or dev client).
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## Links
|
|
84
|
+
|
|
85
|
+
- NPM: https://www.npmjs.com/package/pushwave-client
|
|
86
|
+
- GitHub: https://github.com/luruk-hai/pushwave-client#readme
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## Roadmap (with SaaS)
|
|
91
|
+
|
|
92
|
+
- Server-side validation of Play Integrity / DeviceCheck tokens.
|
|
93
|
+
- Full attestation docs and Play Store setup (enable Integrity API, internal track).
|
|
94
|
+
- Complete registration flow with the PushWave backend.
|
|
@@ -5,10 +5,11 @@ export interface RegisterPushWaveResponse {
|
|
|
5
5
|
success: boolean;
|
|
6
6
|
message?: string;
|
|
7
7
|
}
|
|
8
|
-
export interface
|
|
8
|
+
export interface RegisterPushWaveDTO {
|
|
9
9
|
apiKey: string;
|
|
10
10
|
expoToken: string;
|
|
11
11
|
platform: string;
|
|
12
12
|
appAttestation?: any;
|
|
13
|
+
environment: "development" | "production";
|
|
13
14
|
}
|
|
14
15
|
export default function registerPushWave({ apiKey }: RegisterPushWaveClient): Promise<RegisterPushWaveResponse>;
|
package/dist/registerPushWave.js
CHANGED
|
@@ -32,7 +32,8 @@ async function registerPushWave({ apiKey }) {
|
|
|
32
32
|
apiKey: apiKey,
|
|
33
33
|
expoToken: expoToken,
|
|
34
34
|
platform: react_native_1.Platform.OS,
|
|
35
|
-
appAttestation: appAttestation
|
|
35
|
+
appAttestation: appAttestation,
|
|
36
|
+
environment: __DEV__ ? "development" : "production"
|
|
36
37
|
};
|
|
37
38
|
try {
|
|
38
39
|
const res = await (0, fetch_1.fetchApi)(path, options);
|
package/dist/utils/fetch.js
CHANGED
package/package.json
CHANGED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export interface AndroidAttestationPayload {
|
|
2
|
+
status: "ok";
|
|
3
|
+
platform: "android";
|
|
4
|
+
nonce: string;
|
|
5
|
+
timestamp: number;
|
|
6
|
+
integrityToken: string;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface IosAttestationPayload {
|
|
10
|
+
status: "ok";
|
|
11
|
+
platform: "ios";
|
|
12
|
+
nonce: string;
|
|
13
|
+
timestamp: number;
|
|
14
|
+
deviceCheckToken: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface DisabledAttestation {
|
|
18
|
+
status: "disabled";
|
|
19
|
+
reason: string;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface SkippedAttestation {
|
|
23
|
+
status: "skipped";
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export type ApplicationAttestation =
|
|
27
|
+
| AndroidAttestationPayload
|
|
28
|
+
| IosAttestationPayload
|
|
29
|
+
| DisabledAttestation
|
|
30
|
+
| SkippedAttestation;
|
|
@@ -1,39 +1,9 @@
|
|
|
1
1
|
import { Buffer } from "buffer";
|
|
2
2
|
import { Platform } from "react-native";
|
|
3
3
|
import { getAndroidIntegrityToken, getDeviceCheckToken } from "./native";
|
|
4
|
+
import { ApplicationAttestation, AndroidAttestationPayload, DisabledAttestation, IosAttestationPayload } from "./index";
|
|
4
5
|
|
|
5
|
-
export
|
|
6
|
-
status: "ok";
|
|
7
|
-
platform: "android";
|
|
8
|
-
nonce: string;
|
|
9
|
-
timestamp: number;
|
|
10
|
-
integrityToken: string;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export interface IosAttestationPayload {
|
|
14
|
-
status: "ok";
|
|
15
|
-
platform: "ios";
|
|
16
|
-
nonce: string;
|
|
17
|
-
timestamp: number;
|
|
18
|
-
deviceCheckToken: string;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export interface DisabledAttestation {
|
|
22
|
-
status: "disabled";
|
|
23
|
-
reason: string;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export interface SkippedAttestation {
|
|
27
|
-
status: "skipped";
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export type ApplicationAttestation =
|
|
31
|
-
| AndroidAttestationPayload
|
|
32
|
-
| IosAttestationPayload
|
|
33
|
-
| DisabledAttestation
|
|
34
|
-
| SkippedAttestation;
|
|
35
|
-
|
|
36
|
-
export default async function getApplicationAttestation(apiKey: string): Promise<ApplicationAttestation> {
|
|
6
|
+
export async function getApplicationAttestation(apiKey: string): Promise<ApplicationAttestation> {
|
|
37
7
|
if (!requiresAttestation(apiKey)) return { status: "skipped" };
|
|
38
8
|
|
|
39
9
|
const { nonce, timestamp } = createNonce();
|
package/src/index.ts
CHANGED
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
import registerPushWave,
|
|
2
|
-
RegisterPushWaveClient,
|
|
3
|
-
RegisterPushWaveResponse,
|
|
4
|
-
} from "./registerPushWave";
|
|
1
|
+
import { registerPushWave, RegisterPushWaveClient, RegisterPushWaveResponse } from "./register";
|
|
5
2
|
|
|
6
3
|
export interface PushWaveClientType {
|
|
7
4
|
init(options: RegisterPushWaveClient): Promise<RegisterPushWaveResponse>;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export interface RegisterPushWaveClient {
|
|
2
|
+
apiKey: string;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
export interface RegisterPushWaveResponse {
|
|
6
|
+
success: boolean;
|
|
7
|
+
message?: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface RegisterPushWaveDTO {
|
|
11
|
+
apiKey: string;
|
|
12
|
+
expoToken: string;
|
|
13
|
+
platform: string;
|
|
14
|
+
appAttestation?: any;
|
|
15
|
+
environment: "development" | "production"
|
|
16
|
+
}
|
|
@@ -1,28 +1,12 @@
|
|
|
1
|
-
import { fetchApi } from "
|
|
2
|
-
import { getExpoToken } from "
|
|
3
|
-
import getApplicationAttestation from "./attestation/getApplicationAttestation";
|
|
1
|
+
import { fetchApi } from "../utils/fetch";
|
|
2
|
+
import { getExpoToken } from "../utils/expoToken";
|
|
4
3
|
import { Platform } from "react-native";
|
|
5
|
-
import { PWLogger } from "
|
|
6
|
-
import { isSecretKey } from "
|
|
4
|
+
import { PWLogger } from "../utils/pwLogger";
|
|
5
|
+
import { isSecretKey } from "../utils/apiKeyCheck";
|
|
6
|
+
import { RegisterPushWaveClient, RegisterPushWaveDTO, RegisterPushWaveResponse } from "./registerPushWave.dto";
|
|
7
|
+
import { getApplicationAttestation } from "../attestation/index";
|
|
7
8
|
|
|
8
|
-
export
|
|
9
|
-
apiKey: string;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export interface RegisterPushWaveResponse {
|
|
13
|
-
success: boolean;
|
|
14
|
-
message?: string;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export interface RegisterPushWaveOptions {
|
|
18
|
-
apiKey: string;
|
|
19
|
-
expoToken: string;
|
|
20
|
-
platform: string;
|
|
21
|
-
appAttestation?: any;
|
|
22
|
-
environment: "development" | "production"
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export default async function registerPushWave(
|
|
9
|
+
export async function registerPushWave(
|
|
26
10
|
{ apiKey }: RegisterPushWaveClient
|
|
27
11
|
): Promise<RegisterPushWaveResponse> {
|
|
28
12
|
|
|
@@ -52,7 +36,7 @@ export default async function registerPushWave(
|
|
|
52
36
|
|
|
53
37
|
const path = "/v1/expo-tokens"
|
|
54
38
|
|
|
55
|
-
const options:
|
|
39
|
+
const options: RegisterPushWaveDTO = {
|
|
56
40
|
apiKey: apiKey,
|
|
57
41
|
expoToken: expoToken,
|
|
58
42
|
platform: Platform.OS,
|
package/src/utils/fetch.ts
CHANGED
package/src/utils/validation.ts
DELETED
|
File without changes
|