react-native-dpop 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.
- package/Dpop.podspec +20 -0
- package/LICENSE +20 -0
- package/README.md +105 -0
- package/android/build.gradle +67 -0
- package/android/src/main/AndroidManifest.xml +2 -0
- package/android/src/main/java/com/dpop/DPoPKeyStore.kt +168 -0
- package/android/src/main/java/com/dpop/DPoPUtils.kt +208 -0
- package/android/src/main/java/com/dpop/DpopModule.kt +302 -0
- package/android/src/main/java/com/dpop/DpopPackage.kt +31 -0
- package/ios/Dpop.h +5 -0
- package/ios/Dpop.mm +21 -0
- package/lib/module/NativeDpop.js +5 -0
- package/lib/module/NativeDpop.js.map +1 -0
- package/lib/module/index.js +68 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/typescript/package.json +1 -0
- package/lib/typescript/src/NativeDpop.d.ts +19 -0
- package/lib/typescript/src/NativeDpop.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +57 -0
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/package.json +120 -0
- package/src/NativeDpop.ts +30 -0
- package/src/index.tsx +145 -0
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
package com.dpop
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.bridge.Arguments
|
|
4
|
+
import com.facebook.react.bridge.Promise
|
|
5
|
+
import com.facebook.react.bridge.ReadableMap
|
|
6
|
+
import com.facebook.react.bridge.ReactApplicationContext
|
|
7
|
+
import java.security.Signature
|
|
8
|
+
import java.util.UUID
|
|
9
|
+
import org.json.JSONObject
|
|
10
|
+
|
|
11
|
+
class DpopModule(reactContext: ReactApplicationContext) :
|
|
12
|
+
NativeDpopSpec(reactContext) {
|
|
13
|
+
private val keyStore = DPoPKeyStore(reactContext)
|
|
14
|
+
|
|
15
|
+
private fun resolveAlias(alias: String?): String {
|
|
16
|
+
return alias ?: DEFAULT_ALIAS
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
override fun assertHardwareBacked(alias: String?, promise: Promise) {
|
|
20
|
+
try {
|
|
21
|
+
val effectiveAlias = resolveAlias(alias)
|
|
22
|
+
if (!keyStore.hasKeyPair(effectiveAlias)) {
|
|
23
|
+
promise.reject("ERR_DPOP_ASSERT_HARDWARE_BACKED", "Key pair not found for alias: $effectiveAlias")
|
|
24
|
+
return
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (!keyStore.isHardwareBacked(effectiveAlias)) {
|
|
28
|
+
promise.reject("ERR_DPOP_ASSERT_HARDWARE_BACKED", "Key pair is not hardware-backed for alias: $effectiveAlias")
|
|
29
|
+
return
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
promise.resolve(null)
|
|
33
|
+
} catch (e: Exception) {
|
|
34
|
+
promise.reject("ERR_DPOP_ASSERT_HARDWARE_BACKED", e.message, e)
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
override fun calculateThumbprint(alias: String?, promise: Promise) {
|
|
39
|
+
try {
|
|
40
|
+
val effectiveAlias = resolveAlias(alias)
|
|
41
|
+
if (!keyStore.hasKeyPair(effectiveAlias)) {
|
|
42
|
+
keyStore.generateKeyPair(effectiveAlias)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
val keyPair = keyStore.getKeyPair(effectiveAlias)
|
|
46
|
+
val coordinates = DPoPUtils.getPublicCoordinates(keyPair.publicKey)
|
|
47
|
+
val thumbprint = DPoPUtils.calculateThumbprint(
|
|
48
|
+
kty = "EC",
|
|
49
|
+
crv = "P-256",
|
|
50
|
+
x = coordinates.first,
|
|
51
|
+
y = coordinates.second
|
|
52
|
+
)
|
|
53
|
+
promise.resolve(thumbprint)
|
|
54
|
+
} catch (e: Exception) {
|
|
55
|
+
promise.reject("ERR_DPOP_CALCULATE_THUMBPRINT", e.message, e)
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
override fun deleteKeyPair(alias: String?, promise: Promise) {
|
|
60
|
+
try {
|
|
61
|
+
val effectiveAlias = resolveAlias(alias)
|
|
62
|
+
keyStore.deleteKeyPair(effectiveAlias)
|
|
63
|
+
promise.resolve(null)
|
|
64
|
+
} catch (e: Exception) {
|
|
65
|
+
promise.reject("ERR_DPOP_DELETE_KEY_PAIR", e.message, e)
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
override fun getKeyInfo(alias: String?, promise: Promise) {
|
|
70
|
+
try {
|
|
71
|
+
val effectiveAlias = resolveAlias(alias)
|
|
72
|
+
if (!keyStore.hasKeyPair(effectiveAlias)) {
|
|
73
|
+
val result = Arguments.createMap().apply {
|
|
74
|
+
putString("alias", effectiveAlias)
|
|
75
|
+
putBoolean("hasKeyPair", false)
|
|
76
|
+
}
|
|
77
|
+
promise.resolve(result)
|
|
78
|
+
return
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
val keyInfo = keyStore.getKeyInfo(effectiveAlias)
|
|
82
|
+
val result = Arguments.createMap().apply {
|
|
83
|
+
putString("alias", keyInfo.alias)
|
|
84
|
+
putString("algorithm", keyInfo.algorithm)
|
|
85
|
+
putString("curve", keyInfo.curve)
|
|
86
|
+
putBoolean("hasKeyPair", true)
|
|
87
|
+
putBoolean("insideSecureHardware", keyInfo.insideSecureHardware)
|
|
88
|
+
putBoolean("strongBoxAvailable", keyInfo.strongBoxAvailable)
|
|
89
|
+
putBoolean("strongBoxBacked", keyInfo.strongBoxBacked)
|
|
90
|
+
if (keyInfo.securityLevel != null) {
|
|
91
|
+
putInt("securityLevel", keyInfo.securityLevel)
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
promise.resolve(result)
|
|
95
|
+
} catch (e: Exception) {
|
|
96
|
+
promise.reject("ERR_DPOP_GET_KEY_INFO", e.message, e)
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
override fun getPublicKeyDer(alias: String?, promise: Promise) {
|
|
101
|
+
try {
|
|
102
|
+
val effectiveAlias = resolveAlias(alias)
|
|
103
|
+
if (!keyStore.hasKeyPair(effectiveAlias)) {
|
|
104
|
+
keyStore.generateKeyPair(effectiveAlias)
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
val keyPair = keyStore.getKeyPair(effectiveAlias)
|
|
108
|
+
promise.resolve(DPoPUtils.base64UrlEncode(keyPair.publicKey.encoded))
|
|
109
|
+
} catch (e: Exception) {
|
|
110
|
+
promise.reject("ERR_DPOP_PUBLIC_KEY", e.message, e)
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
override fun getPublicKeyJwk(alias: String?, promise: Promise) {
|
|
115
|
+
try {
|
|
116
|
+
val effectiveAlias = resolveAlias(alias)
|
|
117
|
+
if (!keyStore.hasKeyPair(effectiveAlias)) {
|
|
118
|
+
keyStore.generateKeyPair(effectiveAlias)
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
val keyPair = keyStore.getKeyPair(effectiveAlias)
|
|
122
|
+
val coordinates = DPoPUtils.getPublicCoordinates(keyPair.publicKey)
|
|
123
|
+
val jwk = Arguments.createMap().apply {
|
|
124
|
+
putString("kty", "EC")
|
|
125
|
+
putString("crv", "P-256")
|
|
126
|
+
putString("x", coordinates.first)
|
|
127
|
+
putString("y", coordinates.second)
|
|
128
|
+
}
|
|
129
|
+
promise.resolve(jwk)
|
|
130
|
+
} catch (e: Exception) {
|
|
131
|
+
promise.reject("ERR_DPOP_PUBLIC_KEY", e.message, e)
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
override fun getPublicKeyRaw(alias: String?, promise: Promise) {
|
|
136
|
+
try {
|
|
137
|
+
val effectiveAlias = resolveAlias(alias)
|
|
138
|
+
if (!keyStore.hasKeyPair(effectiveAlias)) {
|
|
139
|
+
keyStore.generateKeyPair(effectiveAlias)
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
val keyPair = keyStore.getKeyPair(effectiveAlias)
|
|
143
|
+
val raw = DPoPUtils.toRawPublicKey(keyPair.publicKey)
|
|
144
|
+
promise.resolve(DPoPUtils.base64UrlEncode(raw))
|
|
145
|
+
} catch (e: Exception) {
|
|
146
|
+
promise.reject("ERR_DPOP_PUBLIC_KEY", e.message, e)
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
override fun hasKeyPair(alias: String?, promise: Promise) {
|
|
151
|
+
try {
|
|
152
|
+
val effectiveAlias = resolveAlias(alias)
|
|
153
|
+
promise.resolve(keyStore.hasKeyPair(effectiveAlias))
|
|
154
|
+
} catch (e: Exception) {
|
|
155
|
+
promise.reject("ERR_DPOP_HAS_KEY_PAIR", e.message, e)
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
override fun isBoundToAlias(proof: String, alias: String?, promise: Promise) {
|
|
160
|
+
try {
|
|
161
|
+
val effectiveAlias = resolveAlias(alias)
|
|
162
|
+
if (!keyStore.hasKeyPair(effectiveAlias)) {
|
|
163
|
+
keyStore.generateKeyPair(effectiveAlias)
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
val keyPair = keyStore.getKeyPair(effectiveAlias)
|
|
167
|
+
promise.resolve(DPoPUtils.isProofBoundToPublicKey(proof, keyPair.publicKey))
|
|
168
|
+
} catch (e: Exception) {
|
|
169
|
+
promise.reject("ERR_DPOP_IS_BOUND_TO_ALIAS", e.message, e)
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
override fun rotateKeyPair(alias: String?, promise: Promise) {
|
|
174
|
+
try {
|
|
175
|
+
val effectiveAlias = resolveAlias(alias)
|
|
176
|
+
keyStore.generateKeyPair(effectiveAlias)
|
|
177
|
+
promise.resolve(null)
|
|
178
|
+
} catch (e: Exception) {
|
|
179
|
+
promise.reject("ERR_DPOP_ROTATE_KEY_PAIR", e.message, e)
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
override fun signWithDpopPrivateKey(payload: String, alias: String?, promise: Promise) {
|
|
184
|
+
try {
|
|
185
|
+
val effectiveAlias = resolveAlias(alias)
|
|
186
|
+
if (!keyStore.hasKeyPair(effectiveAlias)) {
|
|
187
|
+
keyStore.generateKeyPair(effectiveAlias)
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
val keyPair = keyStore.getKeyPair(effectiveAlias)
|
|
191
|
+
val signature = Signature.getInstance("SHA256withECDSA").apply {
|
|
192
|
+
initSign(keyPair.privateKey)
|
|
193
|
+
update(payload.toByteArray(Charsets.UTF_8))
|
|
194
|
+
}
|
|
195
|
+
val joseSignature = DPoPUtils.derToJose(signature.sign(), partLength = 32)
|
|
196
|
+
promise.resolve(DPoPUtils.base64UrlEncode(joseSignature))
|
|
197
|
+
} catch (e: Exception) {
|
|
198
|
+
promise.reject("ERR_DPOP_SIGN_WITH_PRIVATE_KEY", e.message, e)
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
override fun generateProof(
|
|
203
|
+
htu: String,
|
|
204
|
+
htm: String,
|
|
205
|
+
nonce: String?,
|
|
206
|
+
accessToken: String?,
|
|
207
|
+
additional: ReadableMap?,
|
|
208
|
+
kid: String?,
|
|
209
|
+
jti: String?,
|
|
210
|
+
iat: Double?,
|
|
211
|
+
alias: String?,
|
|
212
|
+
promise: Promise
|
|
213
|
+
) {
|
|
214
|
+
try {
|
|
215
|
+
val effectiveAlias = resolveAlias(alias)
|
|
216
|
+
if (!keyStore.hasKeyPair(effectiveAlias)) {
|
|
217
|
+
keyStore.generateKeyPair(effectiveAlias)
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
val keyPair = keyStore.getKeyPair(effectiveAlias)
|
|
221
|
+
val coordinates = DPoPUtils.getPublicCoordinates(keyPair.publicKey)
|
|
222
|
+
val jwk = JSONObject().apply {
|
|
223
|
+
put("kty", "EC")
|
|
224
|
+
put("crv", "P-256")
|
|
225
|
+
put("x", coordinates.first)
|
|
226
|
+
put("y", coordinates.second)
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
val header = JSONObject().apply {
|
|
230
|
+
put("typ", "dpop+jwt")
|
|
231
|
+
put("alg", "ES256")
|
|
232
|
+
put("jwk", jwk)
|
|
233
|
+
if (!kid.isNullOrBlank()) {
|
|
234
|
+
put("kid", kid)
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
val payload = JSONObject().apply {
|
|
239
|
+
put("jti", if (jti.isNullOrBlank()) UUID.randomUUID().toString() else jti)
|
|
240
|
+
put("htm", htm.uppercase())
|
|
241
|
+
put("htu", htu)
|
|
242
|
+
put("iat", iat?.toLong() ?: (System.currentTimeMillis() / 1000L))
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
if (!nonce.isNullOrBlank()) {
|
|
246
|
+
payload.put("nonce", nonce)
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
if (!accessToken.isNullOrBlank()) {
|
|
250
|
+
payload.put("ath", DPoPUtils.hashAccessToken(accessToken))
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
if (additional != null) {
|
|
254
|
+
val additionalJson = DPoPUtils.toJsonObject(additional)
|
|
255
|
+
val keys = additionalJson.keys()
|
|
256
|
+
while (keys.hasNext()) {
|
|
257
|
+
val key = keys.next()
|
|
258
|
+
payload.put(key, additionalJson.get(key))
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
val headerSegment = DPoPUtils.base64UrlEncode(header.toString().toByteArray(Charsets.UTF_8))
|
|
263
|
+
val payloadSegment = DPoPUtils.base64UrlEncode(payload.toString().toByteArray(Charsets.UTF_8))
|
|
264
|
+
val signingInput = "$headerSegment.$payloadSegment"
|
|
265
|
+
|
|
266
|
+
val signature = Signature.getInstance("SHA256withECDSA").apply {
|
|
267
|
+
initSign(keyPair.privateKey)
|
|
268
|
+
update(signingInput.toByteArray(Charsets.UTF_8))
|
|
269
|
+
}
|
|
270
|
+
val joseSignature = DPoPUtils.derToJose(signature.sign(), partLength = 32)
|
|
271
|
+
val jwt = "$signingInput.${DPoPUtils.base64UrlEncode(joseSignature)}"
|
|
272
|
+
|
|
273
|
+
val proofContext = Arguments.createMap().apply {
|
|
274
|
+
putString("htu", payload.optString("htu"))
|
|
275
|
+
putString("htm", payload.optString("htm"))
|
|
276
|
+
putString("nonce", if (payload.has("nonce")) payload.optString("nonce") else null)
|
|
277
|
+
putString("ath", if (payload.has("ath")) payload.optString("ath") else null)
|
|
278
|
+
putString("kid", if (header.has("kid")) header.optString("kid") else null)
|
|
279
|
+
putString("jti", payload.optString("jti"))
|
|
280
|
+
putDouble("iat", payload.optLong("iat").toDouble())
|
|
281
|
+
if (additional != null) {
|
|
282
|
+
putMap("additional", DPoPUtils.readableMapToWritableMap(additional))
|
|
283
|
+
} else {
|
|
284
|
+
putNull("additional")
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
val result = Arguments.createMap().apply {
|
|
289
|
+
putString("proof", jwt)
|
|
290
|
+
putMap("proofContext", proofContext)
|
|
291
|
+
}
|
|
292
|
+
promise.resolve(result)
|
|
293
|
+
} catch (e: Exception) {
|
|
294
|
+
promise.reject("ERR_DPOP_GENERATE_PROOF", e.message, e)
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
companion object {
|
|
299
|
+
private const val DEFAULT_ALIAS = "react-native-dpop"
|
|
300
|
+
const val NAME = NativeDpopSpec.NAME
|
|
301
|
+
}
|
|
302
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
package com.dpop
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.BaseReactPackage
|
|
4
|
+
import com.facebook.react.bridge.NativeModule
|
|
5
|
+
import com.facebook.react.bridge.ReactApplicationContext
|
|
6
|
+
import com.facebook.react.module.model.ReactModuleInfo
|
|
7
|
+
import com.facebook.react.module.model.ReactModuleInfoProvider
|
|
8
|
+
import java.util.HashMap
|
|
9
|
+
|
|
10
|
+
class DpopPackage : BaseReactPackage() {
|
|
11
|
+
override fun getModule(name: String, reactContext: ReactApplicationContext): NativeModule? {
|
|
12
|
+
return if (name == DpopModule.NAME) {
|
|
13
|
+
DpopModule(reactContext)
|
|
14
|
+
} else {
|
|
15
|
+
null
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
override fun getReactModuleInfoProvider() = ReactModuleInfoProvider {
|
|
20
|
+
mapOf(
|
|
21
|
+
DpopModule.NAME to ReactModuleInfo(
|
|
22
|
+
name = DpopModule.NAME,
|
|
23
|
+
className = DpopModule.NAME,
|
|
24
|
+
canOverrideExistingModule = false,
|
|
25
|
+
needsEagerInit = false,
|
|
26
|
+
isCxxModule = false,
|
|
27
|
+
isTurboModule = true
|
|
28
|
+
)
|
|
29
|
+
)
|
|
30
|
+
}
|
|
31
|
+
}
|
package/ios/Dpop.h
ADDED
package/ios/Dpop.mm
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
#import "Dpop.h"
|
|
2
|
+
|
|
3
|
+
@implementation Dpop
|
|
4
|
+
- (NSNumber *)multiply:(double)a b:(double)b {
|
|
5
|
+
NSNumber *result = @(a * b);
|
|
6
|
+
|
|
7
|
+
return result;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
|
|
11
|
+
(const facebook::react::ObjCTurboModule::InitParams &)params
|
|
12
|
+
{
|
|
13
|
+
return std::make_shared<facebook::react::NativeDpopSpecJSI>(params);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
+ (NSString *)moduleName
|
|
17
|
+
{
|
|
18
|
+
return @"Dpop";
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
@end
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["TurboModuleRegistry","getEnforcing"],"sourceRoot":"../../src","sources":["NativeDpop.ts"],"mappings":";;AACA,SAASA,mBAAmB,QAAQ,cAAc;AA4BlD,eAAeA,mBAAmB,CAACC,YAAY,CAAO,MAAM,CAAC","ignoreList":[]}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { Platform } from 'react-native';
|
|
4
|
+
import Dpop from "./NativeDpop.js";
|
|
5
|
+
const LINKING_ERROR = 'Dpop module nao encontrado. Verifique se o app Android foi recompilado apos adicionar o modulo nativo.';
|
|
6
|
+
function requireAndroid() {
|
|
7
|
+
if (Platform.OS !== 'android') {
|
|
8
|
+
throw new Error('react-native-dpop (MVP atual) suporta somente Android.');
|
|
9
|
+
}
|
|
10
|
+
if (!Dpop) {
|
|
11
|
+
throw new Error(LINKING_ERROR);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
export class DPoP {
|
|
15
|
+
constructor(proof, proofContext, alias) {
|
|
16
|
+
this.proof = proof;
|
|
17
|
+
this.proofContext = proofContext;
|
|
18
|
+
this.alias = alias;
|
|
19
|
+
}
|
|
20
|
+
async calculateThumbprint() {
|
|
21
|
+
requireAndroid();
|
|
22
|
+
return Dpop.calculateThumbprint(this.alias ?? null);
|
|
23
|
+
}
|
|
24
|
+
async getPublicKey(format) {
|
|
25
|
+
requireAndroid();
|
|
26
|
+
if (format === 'DER') {
|
|
27
|
+
return Dpop.getPublicKeyDer(this.alias ?? null);
|
|
28
|
+
}
|
|
29
|
+
if (format === 'RAW') {
|
|
30
|
+
return Dpop.getPublicKeyRaw(this.alias ?? null);
|
|
31
|
+
}
|
|
32
|
+
return Dpop.getPublicKeyJwk(this.alias ?? null);
|
|
33
|
+
}
|
|
34
|
+
async signWithDpopPrivateKey(payload) {
|
|
35
|
+
requireAndroid();
|
|
36
|
+
return Dpop.signWithDpopPrivateKey(payload, this.alias ?? null);
|
|
37
|
+
}
|
|
38
|
+
async isBoundToAlias(alias) {
|
|
39
|
+
requireAndroid();
|
|
40
|
+
return Dpop.isBoundToAlias(this.proof, alias ?? this.alias ?? null);
|
|
41
|
+
}
|
|
42
|
+
static async generateProof(input) {
|
|
43
|
+
requireAndroid();
|
|
44
|
+
const result = await Dpop.generateProof(input.htu, input.htm, input.nonce ?? null, input.accessToken ?? null, input.additional ?? null, input.kid ?? null, input.jti ?? null, input.iat ?? null, input.alias ?? null);
|
|
45
|
+
return new DPoP(result.proof, result.proofContext, input.alias);
|
|
46
|
+
}
|
|
47
|
+
static async assertHardwareBacked(alias) {
|
|
48
|
+
requireAndroid();
|
|
49
|
+
await Dpop.assertHardwareBacked(alias ?? null);
|
|
50
|
+
}
|
|
51
|
+
static async deleteKeyPair(alias) {
|
|
52
|
+
requireAndroid();
|
|
53
|
+
await Dpop.deleteKeyPair(alias ?? null);
|
|
54
|
+
}
|
|
55
|
+
static async getKeyInfo(alias) {
|
|
56
|
+
requireAndroid();
|
|
57
|
+
return Dpop.getKeyInfo(alias ?? null);
|
|
58
|
+
}
|
|
59
|
+
static async hasKeyPair(alias) {
|
|
60
|
+
requireAndroid();
|
|
61
|
+
return Dpop.hasKeyPair(alias ?? null);
|
|
62
|
+
}
|
|
63
|
+
static async rotateKeyPair(alias) {
|
|
64
|
+
requireAndroid();
|
|
65
|
+
await Dpop.rotateKeyPair(alias ?? null);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["Platform","Dpop","LINKING_ERROR","requireAndroid","OS","Error","DPoP","constructor","proof","proofContext","alias","calculateThumbprint","getPublicKey","format","getPublicKeyDer","getPublicKeyRaw","getPublicKeyJwk","signWithDpopPrivateKey","payload","isBoundToAlias","generateProof","input","result","htu","htm","nonce","accessToken","additional","kid","jti","iat","assertHardwareBacked","deleteKeyPair","getKeyInfo","hasKeyPair","rotateKeyPair"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"type":"module"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"type":"module"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { TurboModule } from 'react-native';
|
|
2
|
+
import type { UnsafeObject } from 'react-native/Libraries/Types/CodegenTypes';
|
|
3
|
+
export interface Spec extends TurboModule {
|
|
4
|
+
assertHardwareBacked(alias: string | null): Promise<void>;
|
|
5
|
+
calculateThumbprint(alias: string | null): Promise<string>;
|
|
6
|
+
deleteKeyPair(alias: string | null): Promise<void>;
|
|
7
|
+
getKeyInfo(alias: string | null): Promise<UnsafeObject>;
|
|
8
|
+
getPublicKeyDer(alias: string | null): Promise<string>;
|
|
9
|
+
getPublicKeyJwk(alias: string | null): Promise<UnsafeObject>;
|
|
10
|
+
getPublicKeyRaw(alias: string | null): Promise<string>;
|
|
11
|
+
hasKeyPair(alias: string | null): Promise<boolean>;
|
|
12
|
+
isBoundToAlias(proof: string, alias: string | null): Promise<boolean>;
|
|
13
|
+
rotateKeyPair(alias: string | null): Promise<void>;
|
|
14
|
+
signWithDpopPrivateKey(payload: string, alias: string | null): Promise<string>;
|
|
15
|
+
generateProof(htu: string, htm: string, nonce: string | null, accessToken: string | null, additional: UnsafeObject | null, kid: string | null, jti: string | null, iat: number | null, alias: string | null): Promise<UnsafeObject>;
|
|
16
|
+
}
|
|
17
|
+
declare const _default: Spec;
|
|
18
|
+
export default _default;
|
|
19
|
+
//# sourceMappingURL=NativeDpop.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NativeDpop.d.ts","sourceRoot":"","sources":["../../../src/NativeDpop.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEhD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2CAA2C,CAAC;AAE9E,MAAM,WAAW,IAAK,SAAQ,WAAW;IACvC,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1D,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC3D,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnD,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;IACxD,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACvD,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;IAC7D,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACvD,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACnD,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACtE,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnD,sBAAsB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC/E,aAAa,CACX,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,GAAG,IAAI,EACpB,WAAW,EAAE,MAAM,GAAG,IAAI,EAC1B,UAAU,EAAE,YAAY,GAAG,IAAI,EAC/B,GAAG,EAAE,MAAM,GAAG,IAAI,EAClB,GAAG,EAAE,MAAM,GAAG,IAAI,EAClB,GAAG,EAAE,MAAM,GAAG,IAAI,EAClB,KAAK,EAAE,MAAM,GAAG,IAAI,GACnB,OAAO,CAAC,YAAY,CAAC,CAAC;CAC1B;;AAED,wBAA8D"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
type AdditionalClaims = Record<string, unknown>;
|
|
2
|
+
export type PublicJwk = {
|
|
3
|
+
kty: 'EC';
|
|
4
|
+
crv: 'P-256';
|
|
5
|
+
x: string;
|
|
6
|
+
y: string;
|
|
7
|
+
};
|
|
8
|
+
export type PublicKeyFormat = 'JWK' | 'DER' | 'RAW';
|
|
9
|
+
export type DPoPKeyInfo = {
|
|
10
|
+
alias: string;
|
|
11
|
+
hasKeyPair: boolean;
|
|
12
|
+
algorithm?: string;
|
|
13
|
+
curve?: string;
|
|
14
|
+
insideSecureHardware?: boolean;
|
|
15
|
+
securityLevel?: number;
|
|
16
|
+
strongBoxAvailable?: boolean;
|
|
17
|
+
strongBoxBacked?: boolean;
|
|
18
|
+
};
|
|
19
|
+
export type GenerateProofInput = {
|
|
20
|
+
htu: string;
|
|
21
|
+
htm: string;
|
|
22
|
+
nonce?: string;
|
|
23
|
+
accessToken?: string;
|
|
24
|
+
additional?: AdditionalClaims;
|
|
25
|
+
kid?: string;
|
|
26
|
+
jti?: string;
|
|
27
|
+
iat?: number;
|
|
28
|
+
alias?: string;
|
|
29
|
+
};
|
|
30
|
+
export type DPoPProofContext = {
|
|
31
|
+
htu: string;
|
|
32
|
+
htm: string;
|
|
33
|
+
nonce: string | null;
|
|
34
|
+
ath: string | null;
|
|
35
|
+
additional: AdditionalClaims | null;
|
|
36
|
+
kid: string | null;
|
|
37
|
+
jti: string;
|
|
38
|
+
iat: number;
|
|
39
|
+
};
|
|
40
|
+
export declare class DPoP {
|
|
41
|
+
readonly proof: string;
|
|
42
|
+
readonly alias?: string;
|
|
43
|
+
readonly proofContext: DPoPProofContext;
|
|
44
|
+
private constructor();
|
|
45
|
+
calculateThumbprint(): Promise<string>;
|
|
46
|
+
getPublicKey(format: PublicKeyFormat): Promise<PublicJwk | string>;
|
|
47
|
+
signWithDpopPrivateKey(payload: string): Promise<string>;
|
|
48
|
+
isBoundToAlias(alias?: string): Promise<boolean>;
|
|
49
|
+
static generateProof(input: GenerateProofInput): Promise<DPoP>;
|
|
50
|
+
static assertHardwareBacked(alias?: string): Promise<void>;
|
|
51
|
+
static deleteKeyPair(alias?: string): Promise<void>;
|
|
52
|
+
static getKeyInfo(alias?: string): Promise<DPoPKeyInfo>;
|
|
53
|
+
static hasKeyPair(alias?: string): Promise<boolean>;
|
|
54
|
+
static rotateKeyPair(alias?: string): Promise<void>;
|
|
55
|
+
}
|
|
56
|
+
export {};
|
|
57
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AAGA,KAAK,gBAAgB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEhD,MAAM,MAAM,SAAS,GAAG;IACtB,GAAG,EAAE,IAAI,CAAC;IACV,GAAG,EAAE,OAAO,CAAC;IACb,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,CAAC;AAEpD,MAAM,MAAM,WAAW,GAAG;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,OAAO,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,UAAU,EAAE,gBAAgB,GAAG,IAAI,CAAC;IACpC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;CACb,CAAC;AAmBF,qBAAa,IAAI;IACf,SAAgB,KAAK,EAAE,MAAM,CAAC;IAC9B,SAAgB,KAAK,CAAC,EAAE,MAAM,CAAC;IAC/B,SAAgB,YAAY,EAAE,gBAAgB,CAAC;IAE/C,OAAO;IAMM,mBAAmB,IAAI,OAAO,CAAC,MAAM,CAAC;IAKtC,YAAY,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,SAAS,GAAG,MAAM,CAAC;IAYlE,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAKxD,cAAc,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;WAKzC,aAAa,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;WAiBvD,oBAAoB,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;WAKnD,aAAa,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;WAK5C,UAAU,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;WAKhD,UAAU,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;WAK5C,aAAa,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAIjE"}
|
package/package.json
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "react-native-dpop",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "React Native library for DPoP proof generation and key management.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"android",
|
|
7
|
+
"ios",
|
|
8
|
+
"react-native"
|
|
9
|
+
],
|
|
10
|
+
"homepage": "https://github.com/Cirilord/react-native-dpop#readme",
|
|
11
|
+
"repository": {
|
|
12
|
+
"type": "git",
|
|
13
|
+
"url": "git+https://github.com/Cirilord/react-native-dpop.git"
|
|
14
|
+
},
|
|
15
|
+
"bugs": {
|
|
16
|
+
"url": "https://github.com/Cirilord/react-native-dpop/issues"
|
|
17
|
+
},
|
|
18
|
+
"license": "MIT",
|
|
19
|
+
"author": "Pedro Cirilo <phscirilo123@gmail.com> (https://github.com/Cirilord)",
|
|
20
|
+
"main": "./lib/module/index.js",
|
|
21
|
+
"types": "./lib/typescript/src/index.d.ts",
|
|
22
|
+
"exports": {
|
|
23
|
+
".": {
|
|
24
|
+
"source": "./src/index.tsx",
|
|
25
|
+
"types": "./lib/typescript/src/index.d.ts",
|
|
26
|
+
"default": "./lib/module/index.js"
|
|
27
|
+
},
|
|
28
|
+
"./package.json": "./package.json"
|
|
29
|
+
},
|
|
30
|
+
"files": [
|
|
31
|
+
"src",
|
|
32
|
+
"lib",
|
|
33
|
+
"android",
|
|
34
|
+
"ios",
|
|
35
|
+
"cpp",
|
|
36
|
+
"*.podspec",
|
|
37
|
+
"react-native.config.js",
|
|
38
|
+
"!ios/build",
|
|
39
|
+
"!android/build",
|
|
40
|
+
"!android/gradle",
|
|
41
|
+
"!android/gradlew",
|
|
42
|
+
"!android/gradlew.bat",
|
|
43
|
+
"!android/local.properties",
|
|
44
|
+
"!**/__tests__",
|
|
45
|
+
"!**/__fixtures__",
|
|
46
|
+
"!**/__mocks__",
|
|
47
|
+
"!**/.*"
|
|
48
|
+
],
|
|
49
|
+
"scripts": {
|
|
50
|
+
"clean": "del-cli android/build example/android/build example/android/app/build example/ios/build lib",
|
|
51
|
+
"example": "yarn workspace react-native-dpop-example",
|
|
52
|
+
"lint": "eslint \"**/*.{js,ts,tsx}\"",
|
|
53
|
+
"prepare": "bob build",
|
|
54
|
+
"release": "release-it --only-version",
|
|
55
|
+
"test": "jest",
|
|
56
|
+
"typecheck": "tsc"
|
|
57
|
+
},
|
|
58
|
+
"publishConfig": {
|
|
59
|
+
"registry": "https://registry.npmjs.org/"
|
|
60
|
+
},
|
|
61
|
+
"peerDependencies": {
|
|
62
|
+
"react": "*",
|
|
63
|
+
"react-native": "*"
|
|
64
|
+
},
|
|
65
|
+
"devDependencies": {
|
|
66
|
+
"@commitlint/config-conventional": "^19.8.1",
|
|
67
|
+
"@eslint/compat": "^1.3.2",
|
|
68
|
+
"@eslint/eslintrc": "^3.3.1",
|
|
69
|
+
"@eslint/js": "^9.35.0",
|
|
70
|
+
"@react-native/babel-preset": "0.83.0",
|
|
71
|
+
"@react-native/eslint-config": "0.83.0",
|
|
72
|
+
"@release-it/conventional-changelog": "^10.0.1",
|
|
73
|
+
"@types/jest": "^29.5.14",
|
|
74
|
+
"@types/react": "^19.2.0",
|
|
75
|
+
"commitlint": "^19.8.1",
|
|
76
|
+
"del-cli": "^6.0.0",
|
|
77
|
+
"eslint": "^9.35.0",
|
|
78
|
+
"eslint-config-prettier": "^10.1.8",
|
|
79
|
+
"eslint-plugin-prettier": "^5.5.4",
|
|
80
|
+
"jest": "^29.7.0",
|
|
81
|
+
"lefthook": "^2.0.3",
|
|
82
|
+
"prettier": "^2.8.8",
|
|
83
|
+
"react": "19.2.0",
|
|
84
|
+
"react-native": "0.83.0",
|
|
85
|
+
"react-native-builder-bob": "^0.40.18",
|
|
86
|
+
"release-it": "^19.0.4",
|
|
87
|
+
"turbo": "^2.5.6",
|
|
88
|
+
"typescript": "^5.9.2"
|
|
89
|
+
},
|
|
90
|
+
"workspaces": [
|
|
91
|
+
"example"
|
|
92
|
+
],
|
|
93
|
+
"packageManager": "yarn@4.11.0",
|
|
94
|
+
"react-native-builder-bob": {
|
|
95
|
+
"source": "src",
|
|
96
|
+
"output": "lib",
|
|
97
|
+
"targets": [
|
|
98
|
+
[
|
|
99
|
+
"module",
|
|
100
|
+
{
|
|
101
|
+
"esm": true
|
|
102
|
+
}
|
|
103
|
+
],
|
|
104
|
+
[
|
|
105
|
+
"typescript",
|
|
106
|
+
{
|
|
107
|
+
"project": "tsconfig.build.json"
|
|
108
|
+
}
|
|
109
|
+
]
|
|
110
|
+
]
|
|
111
|
+
},
|
|
112
|
+
"codegenConfig": {
|
|
113
|
+
"name": "DpopSpec",
|
|
114
|
+
"type": "modules",
|
|
115
|
+
"jsSrcsDir": "src",
|
|
116
|
+
"android": {
|
|
117
|
+
"javaPackageName": "com.dpop"
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|