react-native-app-attestation 0.1.0

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.
@@ -0,0 +1,126 @@
1
+ "use strict";
2
+ // src/AttestationService.ts
3
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
4
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
5
+ return new (P || (P = Promise))(function (resolve, reject) {
6
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
7
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
8
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
9
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
10
+ });
11
+ };
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.AttestationService = void 0;
14
+ const react_native_1 = require("react-native");
15
+ class AttestationService {
16
+ constructor(config) {
17
+ var _a;
18
+ this.cachedToken = null;
19
+ this.tokenExpiry = null;
20
+ this.config = config;
21
+ this.cacheDuration = (_a = config.tokenCacheDurationMs) !== null && _a !== void 0 ? _a : 10 * 60 * 1000;
22
+ }
23
+ log(msg) {
24
+ if (this.config.debug)
25
+ console.log(`[Attestation] ${msg}`);
26
+ }
27
+ // Backend se nonce fetch karo
28
+ fetchNonce() {
29
+ return __awaiter(this, void 0, void 0, function* () {
30
+ const response = yield fetch(this.config.nonceEndpoint);
31
+ const data = yield response.json();
32
+ if (!data.nonce)
33
+ throw new Error('Nonce nahi mila backend se');
34
+ return data.nonce;
35
+ });
36
+ }
37
+ // Android — Play Integrity
38
+ getAndroidToken() {
39
+ return __awaiter(this, void 0, void 0, function* () {
40
+ try {
41
+ const { PlayIntegrityModule } = react_native_1.NativeModules;
42
+ if (!PlayIntegrityModule) {
43
+ this.log('PlayIntegrityModule nahi mila');
44
+ return null;
45
+ }
46
+ const nonce = yield this.fetchNonce();
47
+ const token = yield PlayIntegrityModule
48
+ .getAttestationToken(nonce);
49
+ this.log('Android token mila!');
50
+ return token;
51
+ }
52
+ catch (error) {
53
+ this.log(`Android error: ${error}`);
54
+ return null;
55
+ }
56
+ });
57
+ }
58
+ // iOS — App Attest
59
+ getIOSToken() {
60
+ return __awaiter(this, void 0, void 0, function* () {
61
+ try {
62
+ const { AppAttestModule } = react_native_1.NativeModules;
63
+ if (!AppAttestModule) {
64
+ this.log('AppAttestModule nahi mila');
65
+ return null;
66
+ }
67
+ const challenge = yield this.fetchNonce();
68
+ const token = yield AppAttestModule
69
+ .getAttestationToken(challenge);
70
+ this.log('iOS token mila!');
71
+ return token;
72
+ }
73
+ catch (error) {
74
+ this.log(`iOS error: ${error}`);
75
+ return null;
76
+ }
77
+ });
78
+ }
79
+ // Main function
80
+ getToken() {
81
+ return __awaiter(this, arguments, void 0, function* (forceRefresh = false) {
82
+ const now = Date.now();
83
+ const platform = react_native_1.Platform.OS;
84
+ // Cache valid hai?
85
+ if (!forceRefresh &&
86
+ this.cachedToken &&
87
+ this.tokenExpiry &&
88
+ now < this.tokenExpiry) {
89
+ this.log('Cached token use ho raha hai');
90
+ return {
91
+ token: this.cachedToken,
92
+ fromCache: true,
93
+ platform,
94
+ };
95
+ }
96
+ // Fresh token lo
97
+ let token = null;
98
+ if (react_native_1.Platform.OS === 'android') {
99
+ token = yield this.getAndroidToken();
100
+ }
101
+ else if (react_native_1.Platform.OS === 'ios') {
102
+ token = yield this.getIOSToken();
103
+ }
104
+ // Cache karo
105
+ if (token) {
106
+ this.cachedToken = token;
107
+ this.tokenExpiry = now + this.cacheDuration;
108
+ this.log(`Token cached — ${this.cacheDuration / 60000} min valid`);
109
+ }
110
+ return { token, fromCache: false, platform };
111
+ });
112
+ }
113
+ // Sensitive operations ke liye
114
+ getFreshToken() {
115
+ return __awaiter(this, void 0, void 0, function* () {
116
+ return this.getToken(true);
117
+ });
118
+ }
119
+ // Logout pe call karo
120
+ clearCache() {
121
+ this.cachedToken = null;
122
+ this.tokenExpiry = null;
123
+ this.log('Cache cleared');
124
+ }
125
+ }
126
+ exports.AttestationService = AttestationService;
@@ -0,0 +1,9 @@
1
+ import { StorageAdapter } from './types';
2
+ export declare class DeviceIDService {
3
+ private storage;
4
+ private debug;
5
+ constructor(storage: StorageAdapter, debug?: boolean);
6
+ private log;
7
+ getDeviceID(): Promise<string>;
8
+ resetDeviceID(): Promise<void>;
9
+ }
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+ // src/DeviceIDService.ts
3
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
4
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
5
+ return new (P || (P = Promise))(function (resolve, reject) {
6
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
7
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
8
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
9
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
10
+ });
11
+ };
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.DeviceIDService = void 0;
14
+ const DEVICE_ID_KEY = 'rn_attestation_device_id';
15
+ // Khud ka UUID generator — koi library nahi!
16
+ const generateUUID = () => {
17
+ return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
18
+ const r = (Math.random() * 16) | 0;
19
+ const v = c === 'x' ? r : (r & 0x3) | 0x8;
20
+ return v.toString(16);
21
+ });
22
+ };
23
+ class DeviceIDService {
24
+ constructor(storage, debug = false) {
25
+ this.storage = storage;
26
+ this.debug = debug;
27
+ }
28
+ log(msg) {
29
+ if (this.debug)
30
+ console.log(`[DeviceID] ${msg}`);
31
+ }
32
+ getDeviceID() {
33
+ return __awaiter(this, void 0, void 0, function* () {
34
+ try {
35
+ // Storage se check karo
36
+ let deviceId = yield Promise.resolve(this.storage.get(DEVICE_ID_KEY));
37
+ if (!deviceId) {
38
+ // Pehli baar — naya UUID banao
39
+ deviceId = generateUUID();
40
+ yield Promise.resolve(this.storage.set(DEVICE_ID_KEY, deviceId));
41
+ this.log(`Naya Device ID banaya: ${deviceId}`);
42
+ }
43
+ else {
44
+ this.log(`Existing Device ID mila: ${deviceId}`);
45
+ }
46
+ return deviceId;
47
+ }
48
+ catch (error) {
49
+ this.log(`Error: ${error}`);
50
+ // Fallback — storage fail ho toh bhi app crash na ho
51
+ return generateUUID();
52
+ }
53
+ });
54
+ }
55
+ resetDeviceID() {
56
+ return __awaiter(this, void 0, void 0, function* () {
57
+ yield Promise.resolve(this.storage.delete(DEVICE_ID_KEY));
58
+ this.log('Device ID reset ho gaya');
59
+ });
60
+ }
61
+ }
62
+ exports.DeviceIDService = DeviceIDService;
package/lib/index.d.ts ADDED
@@ -0,0 +1,64 @@
1
+ import { AttestationConfig, SecurityHeaders } from './types';
2
+ export * from './types';
3
+ export { DeviceIDService } from './DeviceIDService';
4
+ export { AttestationService } from './AttestationService';
5
+ export { axiosInterceptor, secureFetch } from './interceptors';
6
+ /**
7
+ * App start pe ek baar call karo
8
+ *
9
+ * MMKV example:
10
+ * initAttestation({
11
+ * storage: {
12
+ * get: (key) => mmkv.getString(key) ?? null,
13
+ * set: (key, val) => mmkv.set(key, val),
14
+ * delete: (key) => mmkv.delete(key),
15
+ * },
16
+ * nonceEndpoint: 'https://api.yourapp.com/auth/nonce',
17
+ * appVersion: '1.4',
18
+ * debug: __DEV__,
19
+ * });
20
+ */
21
+ export declare const initAttestation: (config: AttestationConfig) => void;
22
+ /**
23
+ * Device ID lo
24
+ */
25
+ export declare const getDeviceID: () => Promise<string>;
26
+ /**
27
+ * Attestation token lo (cached ya fresh)
28
+ */
29
+ export declare const getAttestationToken: (forceRefresh?: boolean) => Promise<string | null>;
30
+ /**
31
+ * Sensitive operations ke liye fresh token
32
+ * Payment, Login, OTP pe ye use karo
33
+ */
34
+ export declare const getFreshAttestationToken: () => Promise<string | null>;
35
+ /**
36
+ * Saare security headers ek saath lo
37
+ * Interceptor mein ye use karo
38
+ */
39
+ export declare const getSecurityHeaders: () => Promise<SecurityHeaders>;
40
+ /**
41
+ * Axios interceptor setup
42
+ *
43
+ * import axios from 'axios';
44
+ * import { initAttestation, setupAxios } from 'react-native-app-attestation';
45
+ *
46
+ * const api = axios.create({ baseURL: '...' });
47
+ * setupAxios(api);
48
+ */
49
+ export declare const setupAxios: (axiosInstance: any) => void;
50
+ /**
51
+ * Secure fetch — fetch ki jagah use karo
52
+ *
53
+ * const res = await secureGet('https://api.com/user');
54
+ */
55
+ export declare const secureGet: (url: string, options?: RequestInit) => Promise<Response>;
56
+ export declare const securePost: (url: string, body: unknown, options?: RequestInit) => Promise<Response>;
57
+ /**
58
+ * Logout pe call karo
59
+ */
60
+ export declare const clearAttestationCache: () => void;
61
+ /**
62
+ * Device ID reset karo
63
+ */
64
+ export declare const resetDeviceID: () => Promise<void>;
package/lib/index.js ADDED
@@ -0,0 +1,171 @@
1
+ "use strict";
2
+ // src/index.ts
3
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
+ if (k2 === undefined) k2 = k;
5
+ var desc = Object.getOwnPropertyDescriptor(m, k);
6
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
+ desc = { enumerable: true, get: function() { return m[k]; } };
8
+ }
9
+ Object.defineProperty(o, k2, desc);
10
+ }) : (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ o[k2] = m[k];
13
+ }));
14
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
15
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
16
+ };
17
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
18
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
19
+ return new (P || (P = Promise))(function (resolve, reject) {
20
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
21
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
22
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
23
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
24
+ });
25
+ };
26
+ Object.defineProperty(exports, "__esModule", { value: true });
27
+ exports.resetDeviceID = exports.clearAttestationCache = exports.securePost = exports.secureGet = exports.setupAxios = exports.getSecurityHeaders = exports.getFreshAttestationToken = exports.getAttestationToken = exports.getDeviceID = exports.initAttestation = exports.secureFetch = exports.axiosInterceptor = exports.AttestationService = exports.DeviceIDService = void 0;
28
+ const react_native_1 = require("react-native");
29
+ const DeviceIDService_1 = require("./DeviceIDService");
30
+ const AttestationService_1 = require("./AttestationService");
31
+ const interceptors_1 = require("./interceptors");
32
+ // Re-export — user directly import kar sake
33
+ __exportStar(require("./types"), exports);
34
+ var DeviceIDService_2 = require("./DeviceIDService");
35
+ Object.defineProperty(exports, "DeviceIDService", { enumerable: true, get: function () { return DeviceIDService_2.DeviceIDService; } });
36
+ var AttestationService_2 = require("./AttestationService");
37
+ Object.defineProperty(exports, "AttestationService", { enumerable: true, get: function () { return AttestationService_2.AttestationService; } });
38
+ var interceptors_2 = require("./interceptors");
39
+ Object.defineProperty(exports, "axiosInterceptor", { enumerable: true, get: function () { return interceptors_2.axiosInterceptor; } });
40
+ Object.defineProperty(exports, "secureFetch", { enumerable: true, get: function () { return interceptors_2.secureFetch; } });
41
+ // ========================================
42
+ // SINGLETON — ek baar init, har jagah use
43
+ // ========================================
44
+ let deviceIDService = null;
45
+ let attestationService = null;
46
+ let globalConfig = null;
47
+ /**
48
+ * App start pe ek baar call karo
49
+ *
50
+ * MMKV example:
51
+ * initAttestation({
52
+ * storage: {
53
+ * get: (key) => mmkv.getString(key) ?? null,
54
+ * set: (key, val) => mmkv.set(key, val),
55
+ * delete: (key) => mmkv.delete(key),
56
+ * },
57
+ * nonceEndpoint: 'https://api.yourapp.com/auth/nonce',
58
+ * appVersion: '1.4',
59
+ * debug: __DEV__,
60
+ * });
61
+ */
62
+ const initAttestation = (config) => {
63
+ globalConfig = config;
64
+ deviceIDService = new DeviceIDService_1.DeviceIDService(config.storage, config.debug);
65
+ attestationService = new AttestationService_1.AttestationService(config);
66
+ };
67
+ exports.initAttestation = initAttestation;
68
+ // Init check
69
+ const checkInit = (fnName) => {
70
+ if (!deviceIDService || !attestationService || !globalConfig) {
71
+ throw new Error(`[react-native-app-attestation] ${fnName}() call karne se pehle initAttestation() call karo!`);
72
+ }
73
+ };
74
+ /**
75
+ * Device ID lo
76
+ */
77
+ const getDeviceID = () => __awaiter(void 0, void 0, void 0, function* () {
78
+ checkInit('getDeviceID');
79
+ return deviceIDService.getDeviceID();
80
+ });
81
+ exports.getDeviceID = getDeviceID;
82
+ /**
83
+ * Attestation token lo (cached ya fresh)
84
+ */
85
+ const getAttestationToken = (...args_1) => __awaiter(void 0, [...args_1], void 0, function* (forceRefresh = false) {
86
+ checkInit('getAttestationToken');
87
+ const result = yield attestationService.getToken(forceRefresh);
88
+ return result.token;
89
+ });
90
+ exports.getAttestationToken = getAttestationToken;
91
+ /**
92
+ * Sensitive operations ke liye fresh token
93
+ * Payment, Login, OTP pe ye use karo
94
+ */
95
+ const getFreshAttestationToken = () => __awaiter(void 0, void 0, void 0, function* () {
96
+ checkInit('getFreshAttestationToken');
97
+ const result = yield attestationService.getFreshToken();
98
+ return result.token;
99
+ });
100
+ exports.getFreshAttestationToken = getFreshAttestationToken;
101
+ /**
102
+ * Saare security headers ek saath lo
103
+ * Interceptor mein ye use karo
104
+ */
105
+ const getSecurityHeaders = () => __awaiter(void 0, void 0, void 0, function* () {
106
+ checkInit('getSecurityHeaders');
107
+ const [deviceId, attestationResult] = yield Promise.all([
108
+ deviceIDService.getDeviceID(),
109
+ attestationService.getToken(),
110
+ ]);
111
+ const timestamp = Math.floor(Date.now() / 1000).toString();
112
+ const platform = react_native_1.Platform.OS === 'ios' ? 'iOS' : 'Android';
113
+ const headers = {
114
+ 'User-Agent': `App/${globalConfig.appVersion} (${platform})`,
115
+ 'X-App-Platform': react_native_1.Platform.OS,
116
+ 'X-App-Version': globalConfig.appVersion,
117
+ 'X-Device-ID': deviceId,
118
+ 'X-Timestamp': timestamp,
119
+ };
120
+ if (attestationResult.token) {
121
+ headers['X-Attestation'] = attestationResult.token;
122
+ }
123
+ return headers;
124
+ });
125
+ exports.getSecurityHeaders = getSecurityHeaders;
126
+ /**
127
+ * Axios interceptor setup
128
+ *
129
+ * import axios from 'axios';
130
+ * import { initAttestation, setupAxios } from 'react-native-app-attestation';
131
+ *
132
+ * const api = axios.create({ baseURL: '...' });
133
+ * setupAxios(api);
134
+ */
135
+ const setupAxios = (axiosInstance) => {
136
+ checkInit('setupAxios');
137
+ (0, interceptors_1.axiosInterceptor)(axiosInstance, {
138
+ appVersion: globalConfig.appVersion,
139
+ getHeaders: exports.getSecurityHeaders,
140
+ });
141
+ };
142
+ exports.setupAxios = setupAxios;
143
+ /**
144
+ * Secure fetch — fetch ki jagah use karo
145
+ *
146
+ * const res = await secureGet('https://api.com/user');
147
+ */
148
+ const secureGet = (url, options) => {
149
+ checkInit('secureGet');
150
+ return (0, interceptors_1.secureFetch)(url, options !== null && options !== void 0 ? options : {}, exports.getSecurityHeaders);
151
+ };
152
+ exports.secureGet = secureGet;
153
+ const securePost = (url, body, options) => {
154
+ checkInit('securePost');
155
+ return (0, interceptors_1.secureFetch)(url, Object.assign(Object.assign({}, options), { method: 'POST', body: JSON.stringify(body) }), exports.getSecurityHeaders);
156
+ };
157
+ exports.securePost = securePost;
158
+ /**
159
+ * Logout pe call karo
160
+ */
161
+ const clearAttestationCache = () => {
162
+ attestationService === null || attestationService === void 0 ? void 0 : attestationService.clearCache();
163
+ };
164
+ exports.clearAttestationCache = clearAttestationCache;
165
+ /**
166
+ * Device ID reset karo
167
+ */
168
+ const resetDeviceID = () => __awaiter(void 0, void 0, void 0, function* () {
169
+ yield (deviceIDService === null || deviceIDService === void 0 ? void 0 : deviceIDService.resetDeviceID());
170
+ });
171
+ exports.resetDeviceID = resetDeviceID;
@@ -0,0 +1,18 @@
1
+ import { SecurityHeaders } from './types';
2
+ /**
3
+ * AXIOS ke liye
4
+ *
5
+ * Use karo:
6
+ * axiosInterceptor(api, { appVersion: '1.4', getHeaders })
7
+ */
8
+ export declare const axiosInterceptor: (axiosInstance: any, options: {
9
+ appVersion: string;
10
+ getHeaders: () => Promise<SecurityHeaders>;
11
+ }) => void;
12
+ /**
13
+ * FETCH ke liye
14
+ *
15
+ * Use karo:
16
+ * const res = await secureFetch(url, options, getHeaders)
17
+ */
18
+ export declare const secureFetch: (url: string, options: RequestInit | undefined, getHeaders: () => Promise<SecurityHeaders>) => Promise<Response>;
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ // src/interceptors.ts
3
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
4
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
5
+ return new (P || (P = Promise))(function (resolve, reject) {
6
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
7
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
8
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
9
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
10
+ });
11
+ };
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.secureFetch = exports.axiosInterceptor = void 0;
14
+ /**
15
+ * AXIOS ke liye
16
+ *
17
+ * Use karo:
18
+ * axiosInterceptor(api, { appVersion: '1.4', getHeaders })
19
+ */
20
+ const axiosInterceptor = (axiosInstance, options) => {
21
+ axiosInstance.interceptors.request.use((config) => __awaiter(void 0, void 0, void 0, function* () {
22
+ try {
23
+ // Security headers lo
24
+ const securityHeaders = yield options.getHeaders();
25
+ // Existing headers ke saath merge karo
26
+ config.headers = Object.assign(Object.assign({}, config.headers), securityHeaders);
27
+ }
28
+ catch (error) {
29
+ console.warn('[Attestation] Headers add nahi ho sake:', error);
30
+ // App crash nahi hona chahiye — silently fail
31
+ }
32
+ return config;
33
+ }), (error) => Promise.reject(error));
34
+ };
35
+ exports.axiosInterceptor = axiosInterceptor;
36
+ /**
37
+ * FETCH ke liye
38
+ *
39
+ * Use karo:
40
+ * const res = await secureFetch(url, options, getHeaders)
41
+ */
42
+ const secureFetch = (url_1, ...args_1) => __awaiter(void 0, [url_1, ...args_1], void 0, function* (url, options = {}, getHeaders) {
43
+ try {
44
+ // Security headers lo
45
+ const securityHeaders = yield getHeaders();
46
+ // Existing headers ke saath merge karo
47
+ const mergedHeaders = Object.assign(Object.assign({}, options.headers), securityHeaders);
48
+ return fetch(url, Object.assign(Object.assign({}, options), { headers: mergedHeaders }));
49
+ }
50
+ catch (error) {
51
+ console.warn('[Attestation] secureFetch headers error:', error);
52
+ // Headers add nahi hue — normal fetch karo
53
+ return fetch(url, options);
54
+ }
55
+ });
56
+ exports.secureFetch = secureFetch;
package/lib/types.d.ts ADDED
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Storage interface — user apna storage dega
3
+ * MMKV, AsyncStorage, ya koi bhi
4
+ */
5
+ export interface StorageAdapter {
6
+ get: (key: string) => string | null | Promise<string | null>;
7
+ set: (key: string, value: string) => void | Promise<void>;
8
+ delete: (key: string) => void | Promise<void>;
9
+ }
10
+ /**
11
+ * Package initialize karne ke liye config
12
+ */
13
+ export interface AttestationConfig {
14
+ storage: StorageAdapter;
15
+ nonceEndpoint: string;
16
+ appVersion: string;
17
+ tokenCacheDurationMs?: number;
18
+ debug?: boolean;
19
+ }
20
+ /**
21
+ * Attestation token result
22
+ */
23
+ export interface AttestationResult {
24
+ token: string | null;
25
+ fromCache: boolean;
26
+ platform: 'android' | 'ios';
27
+ }
28
+ /**
29
+ * Security headers jo API call mein jayenge
30
+ */
31
+ export interface SecurityHeaders {
32
+ 'User-Agent': string;
33
+ 'X-App-Platform': string;
34
+ 'X-App-Version': string;
35
+ 'X-Device-ID': string;
36
+ 'X-Timestamp': string;
37
+ 'X-Attestation'?: string;
38
+ }
package/lib/types.js ADDED
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ // src/types.ts
3
+ Object.defineProperty(exports, "__esModule", { value: true });
package/package.json ADDED
@@ -0,0 +1,49 @@
1
+ {
2
+ "name": "react-native-app-attestation",
3
+ "version": "0.1.0",
4
+ "description": "Mobile app attestation for React Native — Android Play Integrity & iOS App Attest",
5
+ "main": "lib/index.js",
6
+ "types": "lib/index.d.ts",
7
+ "files": [
8
+ "src",
9
+ "lib",
10
+ "android",
11
+ "ios",
12
+ "react-native-app-attestation.podspec",
13
+ "README.md"
14
+ ],
15
+ "scripts": {
16
+ "build": "tsc",
17
+ "prepare": "npm run build"
18
+ },
19
+ "keywords": [
20
+ "react-native",
21
+ "attestation",
22
+ "play-integrity",
23
+ "app-attest",
24
+ "security",
25
+ "android",
26
+ "ios"
27
+ ],
28
+ "author": "Madhurmeet Jadhav",
29
+ "license": "MIT",
30
+ "repository": {
31
+ "type": "git",
32
+ "url": "https://github.com/madhurmeetjadhav/react-native-app-attestation"
33
+ },
34
+ "codegenConfig": {
35
+ "name": "ReactNativeAppAttestation",
36
+ "type": "all",
37
+ "jsSrcsDir": "src"
38
+ },
39
+ "react-native": "src/index.ts",
40
+ "source": "src/index.ts",
41
+ "peerDependencies": {
42
+ "react": "*",
43
+ "react-native": "*"
44
+ },
45
+ "devDependencies": {
46
+ "typescript": "^5.0.0",
47
+ "@types/react-native": "^0.72.0"
48
+ }
49
+ }
@@ -0,0 +1,27 @@
1
+ require "json"
2
+
3
+ package = JSON.parse(File.read(File.join(__dir__, "package.json")))
4
+
5
+ Pod::Spec.new do |s|
6
+ s.name = "react-native-app-attestation"
7
+ s.version = package["version"]
8
+ s.summary = package["description"]
9
+ s.homepage = "https://github.com/madhurmeetjadhav/react-native-app-attestation"
10
+ s.license = "MIT"
11
+ s.authors = { "Madhurmeet Jadhav" => "madhurmeetj@gmail.com" }
12
+ s.platforms = { :ios => "14.0" }
13
+ s.source = {
14
+ :git => "https://github.com/madhurmeetjadhav/react-native-app-attestation.git",
15
+ :tag => "#{s.version}"
16
+ }
17
+
18
+ s.source_files = "ios/**/*.{h,m,mm,swift}"
19
+
20
+ s.dependency "React-Core"
21
+
22
+ # Autolinking support
23
+ s.pod_target_xcconfig = {
24
+ "SWIFT_VERSION" => "5.0",
25
+ "DEFINES_MODULE" => "YES"
26
+ }
27
+ end