@react-native-kakao/user 3.1.0 → 3.2.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.
@@ -17,19 +17,66 @@ RCT_EXPORT_METHOD(isKakaoTalkLoginAvailable : (RCTPromiseResolveBlock)
17
17
  resolve reject : (RCTPromiseRejectBlock)reject) {
18
18
  [[self manager] isKakaoTalkLoginAvailable:resolve reject:reject];
19
19
  }
20
- RCT_EXPORT_METHOD(login : (NSArray*)serviceTerms prompts : (NSArray*)
21
- prompts useKakaoAccountLogin : (BOOL)useKakaoAccountLogin scopes : (NSArray*)
22
- scopes nonce : (NSString*)nonce resolve : (RCTPromiseResolveBlock)
23
- resolve reject : (RCTPromiseRejectBlock)reject) {
20
+ RCT_EXPORT_METHOD(
21
+ login : (NSArray*)serviceTerms prompts : (NSArray*)prompts useKakaoAccountLogin : (BOOL)
22
+ useKakaoAccountLogin iosLaunchMethod : (NSString*)iosLaunchMethod scopes : (NSArray*)scopes
23
+ nonce : (NSString*)nonce loginHint : (NSString*)loginHint channelPublicIds : (NSArray*)
24
+ channelPublicIds androidRequestCode : (NSNumber*)androidRequestCode resolve : (
25
+ RCTPromiseResolveBlock)resolve reject : (RCTPromiseRejectBlock)reject) {
24
26
  [[self manager] login:serviceTerms
25
27
  prompts:prompts
26
28
  useKakaoAccountLogin:useKakaoAccountLogin
29
+ iosLaunchMethod:iosLaunchMethod
27
30
  scopes:scopes
28
31
  nonce:nonce
32
+ loginHint:loginHint
33
+ channelPublicIds:channelPublicIds
29
34
  resolve:resolve
30
35
  reject:reject];
31
36
  }
32
37
 
38
+ RCT_EXPORT_METHOD(signup : (NSDictionary*)properties resolve : (RCTPromiseResolveBlock)
39
+ resolve reject : (RCTPromiseRejectBlock)reject) {
40
+ [[self manager] signup:properties resolve:resolve reject:reject];
41
+ }
42
+
43
+ RCT_EXPORT_METHOD(loginWithKakao : (NSString*)uiMode orientation : (NSString*)
44
+ orientation launchMethod : (NSString*)launchMethod prompts : (NSArray*)
45
+ prompts loginHint : (NSString*)loginHint nonce : (NSString*)
46
+ nonce channelPublicIds : (NSArray*)channelPublicIds serviceTerms : (
47
+ NSArray*)serviceTerms resolve : (RCTPromiseResolveBlock)
48
+ resolve reject : (RCTPromiseRejectBlock)reject) {
49
+ [[self manager] loginWithKakao:uiMode
50
+ orientation:orientation
51
+ launchMethod:launchMethod
52
+ prompts:prompts
53
+ loginHint:loginHint
54
+ nonce:nonce
55
+ channelPublicIds:channelPublicIds
56
+ serviceTerms:serviceTerms
57
+ resolve:resolve
58
+ reject:reject];
59
+ }
60
+
61
+ RCT_EXPORT_METHOD(issueAccessTokenWithCode : (NSString*)code codeVerifier : (
62
+ NSString*)codeVerifier redirectUri : (NSString*)redirectUri resolve : (RCTPromiseResolveBlock)
63
+ resolve reject : (RCTPromiseRejectBlock)reject) {
64
+ [[self manager] issueAccessTokenWithCode:code
65
+ codeVerifier:codeVerifier
66
+ redirectUri:redirectUri
67
+ resolve:resolve
68
+ reject:reject];
69
+ }
70
+
71
+ RCT_EXPORT_METHOD(refreshToken : (NSDictionary*)token iosLoggingEnabled : (NSNumber*)
72
+ iosLoggingEnabled resolve : (RCTPromiseResolveBlock)
73
+ resolve reject : (RCTPromiseRejectBlock)reject) {
74
+ [[self manager] refreshToken:token
75
+ loggingEnabled:iosLoggingEnabled
76
+ resolve:resolve
77
+ reject:reject];
78
+ }
79
+
33
80
  RCT_EXPORT_METHOD(logout : (RCTPromiseResolveBlock)resolve reject : (RCTPromiseRejectBlock)reject) {
34
81
  [[self manager] logout:resolve reject:reject];
35
82
  }
@@ -43,6 +90,11 @@ RCT_EXPORT_METHOD(isLogined : (RCTPromiseResolveBlock)resolve reject : (RCTPromi
43
90
  [[self manager] isLogined:resolve reject:reject];
44
91
  }
45
92
 
93
+ RCT_EXPORT_METHOD(hasToken : (RCTPromiseResolveBlock)resolve reject : (RCTPromiseRejectBlock)
94
+ reject) {
95
+ [[self manager] hasToken:resolve reject:reject];
96
+ }
97
+
46
98
  RCT_EXPORT_METHOD(scopes : (NSArray*)scopes resolve : (RCTPromiseResolveBlock)
47
99
  resolve reject : (RCTPromiseRejectBlock)reject) {
48
100
  [[self manager] scopes:scopes resolve:resolve reject:reject];
@@ -53,18 +105,39 @@ RCT_EXPORT_METHOD(revokeScopes : (NSArray*)scopes resolve : (RCTPromiseResolveBl
53
105
  [[self manager] revokeScopes:scopes resolve:resolve reject:reject];
54
106
  }
55
107
 
56
- RCT_EXPORT_METHOD(serviceTerms : (RCTPromiseResolveBlock)resolve reject : (RCTPromiseRejectBlock)
57
- reject) {
58
- [[self manager] serviceTerms:resolve reject:reject];
108
+ RCT_EXPORT_METHOD(serviceTerms : (NSString*)result tags : (NSArray*)tags resolve : (
109
+ RCTPromiseResolveBlock)resolve reject : (RCTPromiseRejectBlock)reject) {
110
+ [[self manager] serviceTerms:result tags:tags resolve:resolve reject:reject];
111
+ }
112
+
113
+ RCT_EXPORT_METHOD(shippingAddresses : (NSNumber*)addressId fromUpdatedAt : (
114
+ NSNumber*)fromUpdatedAt pageSize : (NSNumber*)pageSize resolve : (RCTPromiseResolveBlock)
115
+ resolve reject : (RCTPromiseRejectBlock)reject) {
116
+ [[self manager] shippingAddresses:addressId
117
+ fromUpdatedAt:fromUpdatedAt
118
+ pageSize:pageSize
119
+ resolve:resolve
120
+ reject:reject];
59
121
  }
60
122
 
61
- RCT_EXPORT_METHOD(shippingAddresses : (RCTPromiseResolveBlock)
123
+ RCT_EXPORT_METHOD(revokeServiceTerms : (NSArray*)tags resolve : (RCTPromiseResolveBlock)
62
124
  resolve reject : (RCTPromiseRejectBlock)reject) {
63
- [[self manager] shippingAddresses:resolve reject:reject];
125
+ [[self manager] revokeServiceTerms:tags resolve:resolve reject:reject];
64
126
  }
65
127
 
66
- RCT_EXPORT_METHOD(me : (RCTPromiseResolveBlock)resolve reject : (RCTPromiseRejectBlock)reject) {
67
- [[self manager] me:resolve reject:reject];
128
+ RCT_EXPORT_METHOD(updateProfile : (NSDictionary*)properties resolve : (RCTPromiseResolveBlock)
129
+ resolve reject : (RCTPromiseRejectBlock)reject) {
130
+ [[self manager] updateProfile:properties resolve:resolve reject:reject];
131
+ }
132
+
133
+ RCT_EXPORT_METHOD(me : (NSArray*)propertyKeys secureResource : (NSNumber*)secureResource resolve : (
134
+ RCTPromiseResolveBlock)resolve reject : (RCTPromiseRejectBlock)reject) {
135
+ [[self manager] me:propertyKeys secureResource:secureResource resolve:resolve reject:reject];
136
+ }
137
+
138
+ RCT_EXPORT_METHOD(selectShippingAddress : (RCTPromiseResolveBlock)
139
+ resolve reject : (RCTPromiseRejectBlock)reject) {
140
+ [[self manager] selectShippingAddress:resolve reject:reject];
68
141
  }
69
142
 
70
143
  RCT_EXPORT_METHOD(getAccessToken : (RCTPromiseResolveBlock)resolve reject : (RCTPromiseRejectBlock)
@@ -31,8 +31,11 @@ import RNCKakaoCore
31
31
  _ serviceTerms: [String],
32
32
  prompts: [String],
33
33
  useKakaoAccountLogin: Bool,
34
+ iosLaunchMethod: String,
34
35
  scopes: [String],
35
36
  nonce: String?,
37
+ loginHint: String?,
38
+ channelPublicIds: [String],
36
39
  resolve: @escaping RCTPromiseResolveBlock,
37
40
  reject: @escaping RCTPromiseRejectBlock
38
41
  ) {
@@ -41,47 +44,25 @@ import RNCKakaoCore
41
44
  RNCKakaoUtil.reject(reject, RNCKakaoError.sdkNotInitialized)
42
45
  return
43
46
  }
44
- let callback = { (token: OAuthToken?, error: Error?) in
45
- if let error {
46
- RNCKakaoUtil.reject(reject, error)
47
- } else if let token {
48
- resolve([
49
- "accessToken": token.accessToken,
50
- "refreshToken": token.refreshToken,
51
- "tokenType": token.tokenType,
52
- "idToken": token.idToken as Any,
53
- "accessTokenExpiresAt": token.expiredAt.timeIntervalSince1970,
54
- "refreshTokenExpiresAt": token.refreshTokenExpiredAt.timeIntervalSince1970,
55
- "accessTokenExpiresIn": token.expiresIn,
56
- "refreshTokenExpiresIn": token.refreshTokenExpiresIn,
57
- "scopes": token.scopes ?? []
58
- ])
59
- } else {
60
- RNCKakaoUtil.reject(reject, RNCKakaoError.responseNotFound(name: "token"))
61
- }
62
- }
47
+ let callback = tokenCallback(resolve, reject: reject)
63
48
  let accountLogin = {
64
- var _prompts: [Prompt] = []
65
- for p in prompts {
66
- if p == "Login" {
67
- _prompts.append(.Login)
68
- }
69
- if p == "Cert" {
70
- _prompts.append(.Cert)
71
- }
72
- if p == "Create" {
73
- _prompts.append(.Create)
74
- }
75
- if p == "SelectAccount" {
76
- _prompts.append(.SelectAccount)
77
- }
49
+ let _prompts = self.loginPrompts(prompts)
50
+ if let loginHint {
51
+ UserApi.shared.loginWithKakaoAccount(
52
+ prompts: self.emptyArrayToNil(_prompts),
53
+ loginHint: loginHint,
54
+ nonce: nonce,
55
+ completion: callback
56
+ )
57
+ } else {
58
+ UserApi.shared.loginWithKakaoAccount(
59
+ prompts: self.emptyArrayToNil(_prompts),
60
+ channelPublicIds: self.emptyArrayToNil(channelPublicIds),
61
+ serviceTerms: self.emptyArrayToNil(serviceTerms),
62
+ nonce: nonce,
63
+ completion: callback
64
+ )
78
65
  }
79
- UserApi.shared.loginWithKakaoAccount(
80
- prompts: self.emptyArrayToNil(_prompts),
81
- serviceTerms: self.emptyArrayToNil(serviceTerms),
82
- nonce: nonce,
83
- completion: callback
84
- )
85
66
  }
86
67
 
87
68
  if !scopes.isEmpty {
@@ -103,6 +84,8 @@ import RNCKakaoCore
103
84
  }
104
85
  }
105
86
  UserApi.shared.loginWithKakaoTalk(
87
+ launchMethod: loginLaunchMethod(iosLaunchMethod),
88
+ channelPublicIds: emptyArrayToNil(channelPublicIds),
106
89
  serviceTerms: emptyArrayToNil(serviceTerms),
107
90
  nonce: nonce,
108
91
  completion: talkCallback
@@ -113,6 +96,135 @@ import RNCKakaoCore
113
96
  }
114
97
  }
115
98
 
99
+ @objc public func loginWithKakao(
100
+ _ uiMode: String,
101
+ orientation: String,
102
+ launchMethod: String,
103
+ prompts: [String],
104
+ loginHint: String?,
105
+ nonce: String?,
106
+ channelPublicIds: [String],
107
+ serviceTerms: [String],
108
+ resolve: @escaping RCTPromiseResolveBlock,
109
+ reject: @escaping RCTPromiseRejectBlock
110
+ ) {
111
+ onMain { [self] in
112
+ guard let _ = try? KakaoSDK.shared.appKey() else {
113
+ RNCKakaoUtil.reject(reject, RNCKakaoError.sdkNotInitialized)
114
+ return
115
+ }
116
+ guard nonce == nil else {
117
+ RNCKakaoUtil.reject(
118
+ reject,
119
+ RNCKakaoError
120
+ .unknown(
121
+ "The Kakao iOS login chooser does not forward nonce for account login. Use login instead."
122
+ )
123
+ )
124
+ return
125
+ }
126
+ UserApi.shared.loginWithKakao(
127
+ BridgeConfiguration(
128
+ orientation: LoginOrientation(rawValue: orientation),
129
+ uiMode: LoginUiMode(rawValue: uiMode)
130
+ ),
131
+ loginProperties: LoginConfiguration(
132
+ talk: LoginConfiguration
133
+ .Talk(launchMethod: loginLaunchMethod(launchMethod)),
134
+ account: LoginConfiguration.Account(
135
+ prompts: emptyArrayToNil(loginPrompts(prompts)),
136
+ loginHint: loginHint
137
+ ),
138
+ channelPublicIds: emptyArrayToNil(channelPublicIds),
139
+ serviceTerms: emptyArrayToNil(serviceTerms),
140
+ nonce: nonce
141
+ ),
142
+ completion: tokenCallback(resolve, reject: reject)
143
+ )
144
+ }
145
+ }
146
+
147
+ @objc public func issueAccessTokenWithCode(
148
+ _ code: String,
149
+ codeVerifier: String?,
150
+ redirectUri: String?,
151
+ resolve: @escaping RCTPromiseResolveBlock,
152
+ reject: @escaping RCTPromiseRejectBlock
153
+ ) {
154
+ onMain { [self] in
155
+ guard let _ = try? KakaoSDK.shared.appKey() else {
156
+ RNCKakaoUtil.reject(reject, RNCKakaoError.sdkNotInitialized)
157
+ return
158
+ }
159
+ AuthApi.shared.token(
160
+ code: code,
161
+ codeVerifier: codeVerifier,
162
+ redirectUri: redirectUri ?? KakaoSDK.shared.redirectUri(),
163
+ completion: tokenCallback(resolve, reject: reject)
164
+ )
165
+ }
166
+ }
167
+
168
+ @objc public func refreshToken(
169
+ _ token: [String: Any]?,
170
+ loggingEnabled: NSNumber?,
171
+ resolve: @escaping RCTPromiseResolveBlock,
172
+ reject: @escaping RCTPromiseRejectBlock
173
+ ) {
174
+ onMain { [self] in
175
+ guard let _ = try? KakaoSDK.shared.appKey() else {
176
+ RNCKakaoUtil.reject(reject, RNCKakaoError.sdkNotInitialized)
177
+ return
178
+ }
179
+ var oldToken: OAuthToken?
180
+ if let token {
181
+ guard let accessToken = token["accessToken"] as? String,
182
+ let refreshToken = token["refreshToken"] as? String,
183
+ let accessTokenExpiresAt = token["accessTokenExpiresAt"] as? Double,
184
+ let refreshTokenExpiresAt = token["refreshTokenExpiresAt"] as? Double,
185
+ let scopes = token["scopes"] as? [String]
186
+ else {
187
+ RNCKakaoUtil.reject(reject, SdkError(reason: .BadParameter))
188
+ return
189
+ }
190
+ let now = Date().timeIntervalSince1970
191
+ oldToken = OAuthToken(
192
+ accessToken: accessToken,
193
+ expiresIn: accessTokenExpiresAt - now,
194
+ expiredAt: Date(timeIntervalSince1970: accessTokenExpiresAt),
195
+ tokenType: token["tokenType"] as? String ?? "bearer",
196
+ refreshToken: refreshToken,
197
+ refreshTokenExpiresIn: refreshTokenExpiresAt - now,
198
+ refreshTokenExpiredAt: Date(timeIntervalSince1970: refreshTokenExpiresAt),
199
+ scope: scopes.isEmpty ? nil : scopes.joined(separator: " "),
200
+ scopes: scopes,
201
+ idToken: token["idToken"] as? String
202
+ )
203
+ }
204
+ AuthApi.shared.refreshToken(
205
+ token: oldToken,
206
+ loggingEnabled: loggingEnabled?.boolValue ?? true,
207
+ completion: tokenCallback(resolve, reject: reject)
208
+ )
209
+ }
210
+ }
211
+
212
+ @objc public func signup(
213
+ _ properties: [String: String]?,
214
+ resolve: @escaping RCTPromiseResolveBlock,
215
+ reject: @escaping RCTPromiseRejectBlock
216
+ ) {
217
+ onMain {
218
+ UserApi.shared.signup(properties: properties) { _, error in
219
+ if let error {
220
+ RNCKakaoUtil.reject(reject, error)
221
+ } else {
222
+ resolve(nil)
223
+ }
224
+ }
225
+ }
226
+ }
227
+
116
228
  @objc public func logout(
117
229
  _ resolve: @escaping RCTPromiseResolveBlock,
118
230
  reject: @escaping RCTPromiseRejectBlock
@@ -122,7 +234,7 @@ import RNCKakaoCore
122
234
  if let error {
123
235
  RNCKakaoUtil.reject(reject, error)
124
236
  } else {
125
- resolve(42)
237
+ resolve(nil)
126
238
  }
127
239
  }
128
240
  }
@@ -166,6 +278,15 @@ import RNCKakaoCore
166
278
  }
167
279
  }
168
280
 
281
+ @objc public func hasToken(
282
+ _ resolve: @escaping RCTPromiseResolveBlock,
283
+ reject _: @escaping RCTPromiseRejectBlock
284
+ ) {
285
+ onMain {
286
+ resolve(AuthApi.hasToken())
287
+ }
288
+ }
289
+
169
290
  @objc public func scopes(
170
291
  _ scopes: [String]? = nil,
171
292
  resolve: @escaping RCTPromiseResolveBlock,
@@ -175,18 +296,8 @@ import RNCKakaoCore
175
296
  UserApi.shared.scopes(scopes: emptyArrayToNil(scopes)) { scopeInfo, error in
176
297
  if let error {
177
298
  RNCKakaoUtil.reject(reject, error)
178
- } else if let scopes = scopeInfo?.scopes {
179
- resolve(scopes.map { s in
180
- [
181
- "id": s.id,
182
- "displayName": s.displayName,
183
- "type": s.type.rawValue,
184
- "using": s.using,
185
- "delegated": s.delegated as Any,
186
- "agreed": s.agreed,
187
- "revocable": s.revocable as Any
188
- ]
189
- })
299
+ } else if let scopeInfo {
300
+ resolve(self.mapScopes(scopeInfo.scopes))
190
301
  } else {
191
302
  RNCKakaoUtil.reject(reject, RNCKakaoError.responseNotFound(name: "scopes"))
192
303
  }
@@ -203,8 +314,8 @@ import RNCKakaoCore
203
314
  UserApi.shared.revokeScopes(scopes: scopes) { info, error in
204
315
  if let error {
205
316
  RNCKakaoUtil.reject(reject, error)
206
- } else if info != nil {
207
- resolve(42)
317
+ } else if let info {
318
+ resolve(self.mapScopes(info.scopes))
208
319
  } else {
209
320
  RNCKakaoUtil.reject(reject, RNCKakaoError.responseNotFound(name: "scopeInfo"))
210
321
  }
@@ -213,22 +324,30 @@ import RNCKakaoCore
213
324
  }
214
325
 
215
326
  @objc public func serviceTerms(
216
- _ resolve: @escaping RCTPromiseResolveBlock,
327
+ _ result: String?,
328
+ tags: [String]?,
329
+ resolve: @escaping RCTPromiseResolveBlock,
217
330
  reject: @escaping RCTPromiseRejectBlock
218
331
  ) {
219
332
  onMain {
220
- UserApi.shared.serviceTerms { serviceTerms, error in
333
+ UserApi.shared.serviceTerms(result: result, tags: tags) { serviceTerms, error in
221
334
  if let error {
222
335
  RNCKakaoUtil.reject(reject, error)
223
- } else if let serviceTerms = serviceTerms?.serviceTerms {
224
- resolve(serviceTerms.map {
225
- [
226
- "tag": $0.tag,
227
- "agreedAt": $0.agreedAt?.timeIntervalSince1970 as Any,
228
- "agreed": $0.agreed,
229
- "required": $0.required,
230
- "revocable": $0.revocable
336
+ } else if let serviceTerms {
337
+ resolve((serviceTerms.serviceTerms ?? []).map { term in
338
+ var response: [String: Any] = [
339
+ "tag": term.tag,
340
+ "agreed": term.agreed,
341
+ "required": term.required,
342
+ "revocable": term.revocable
231
343
  ]
344
+ if let agreedAt = term.agreedAt {
345
+ response["agreedAt"] = agreedAt.timeIntervalSince1970
346
+ }
347
+ if let referer = term.referer {
348
+ response["agreedBy"] = referer.rawValue
349
+ }
350
+ return response
232
351
  })
233
352
  } else {
234
353
  RNCKakaoUtil.reject(reject, RNCKakaoError.responseNotFound(name: "serviceTerms"))
@@ -238,11 +357,14 @@ import RNCKakaoCore
238
357
  }
239
358
 
240
359
  @objc public func shippingAddresses(
241
- _ resolve: @escaping RCTPromiseResolveBlock,
360
+ _ addressId: NSNumber?,
361
+ fromUpdatedAt: NSNumber?,
362
+ pageSize: NSNumber?,
363
+ resolve: @escaping RCTPromiseResolveBlock,
242
364
  reject: @escaping RCTPromiseRejectBlock
243
365
  ) {
244
366
  onMain {
245
- UserApi.shared.shippingAddresses { s, error in
367
+ let completion: (UserShippingAddresses?, Error?) -> Void = { s, error in
246
368
  if let error {
247
369
  RNCKakaoUtil.reject(reject, error)
248
370
  } else if let s {
@@ -270,20 +392,91 @@ import RNCKakaoCore
270
392
  RNCKakaoUtil.reject(reject, RNCKakaoError.responseNotFound(name: "shippingAddresses"))
271
393
  }
272
394
  }
395
+ if let addressId {
396
+ UserApi.shared.shippingAddresses(addressId: addressId.int64Value, completion: completion)
397
+ } else {
398
+ UserApi.shared.shippingAddresses(
399
+ fromUpdatedAt: fromUpdatedAt.map { Date(timeIntervalSince1970: $0.doubleValue) },
400
+ pageSize: pageSize?.intValue,
401
+ completion: completion
402
+ )
403
+ }
273
404
  }
274
405
  }
275
406
 
276
- @objc public func me(
407
+ @objc public func revokeServiceTerms(
408
+ _ tags: [String],
409
+ resolve: @escaping RCTPromiseResolveBlock,
410
+ reject: @escaping RCTPromiseRejectBlock
411
+ ) {
412
+ onMain {
413
+ UserApi.shared.revokeServiceTerms(tags: tags) { response, error in
414
+ if let error {
415
+ RNCKakaoUtil.reject(reject, error)
416
+ } else if let response {
417
+ resolve((response.revokedServiceTerms ?? []).map {
418
+ ["tag": $0.tag, "agreed": $0.agreed]
419
+ })
420
+ } else {
421
+ RNCKakaoUtil.reject(reject, RNCKakaoError.responseNotFound(name: "revokeServiceTerms"))
422
+ }
423
+ }
424
+ }
425
+ }
426
+
427
+ @objc public func selectShippingAddress(
277
428
  _ resolve: @escaping RCTPromiseResolveBlock,
278
429
  reject: @escaping RCTPromiseRejectBlock
279
430
  ) {
280
431
  onMain {
281
- UserApi.shared.me { user, error in
432
+ UserApi.shared.selectShippingAddress { addressId, error in
433
+ if let error {
434
+ RNCKakaoUtil.reject(reject, error)
435
+ } else if let addressId {
436
+ resolve(addressId)
437
+ } else {
438
+ RNCKakaoUtil.reject(reject, RNCKakaoError.responseNotFound(name: "addressId"))
439
+ }
440
+ }
441
+ }
442
+ }
443
+
444
+ @objc public func updateProfile(
445
+ _ properties: [String: String],
446
+ resolve: @escaping RCTPromiseResolveBlock,
447
+ reject: @escaping RCTPromiseRejectBlock
448
+ ) {
449
+ onMain {
450
+ UserApi.shared.updateProfile(properties: properties) { error in
451
+ if let error {
452
+ RNCKakaoUtil.reject(reject, error)
453
+ } else {
454
+ resolve(nil)
455
+ }
456
+ }
457
+ }
458
+ }
459
+
460
+ @objc public func me(
461
+ _ propertyKeys: [String]?,
462
+ secureResource: NSNumber?,
463
+ resolve: @escaping RCTPromiseResolveBlock,
464
+ reject: @escaping RCTPromiseRejectBlock
465
+ ) {
466
+ onMain {
467
+ UserApi.shared.me(
468
+ propertyKeys: propertyKeys,
469
+ secureResource: secureResource?.boolValue ?? true
470
+ ) { user, error in
282
471
  if let error {
283
472
  RNCKakaoUtil.reject(reject, error)
284
473
  } else if let user {
285
474
  resolve([
286
475
  "id": user.id as Any,
476
+ "properties": user.properties ?? [:],
477
+ "uuid": user.uuid as Any,
478
+ "groupUserToken": user.groupUserToken as Any,
479
+ "hasSignedUp": user.hasSignedUp as Any,
287
480
  "connectedAt": user.connectedAt?.timeIntervalSince1970 as Any,
288
481
  "synchedAt": user.synchedAt?.timeIntervalSince1970 as Any,
289
482
  "name": user.kakaoAccount?.name as Any,
@@ -292,10 +485,12 @@ import RNCKakaoCore
292
485
  "profileImageUrl": user.kakaoAccount?.profile?.profileImageUrl?.absoluteString as Any,
293
486
  "thumbnailImageUrl": user.kakaoAccount?.profile?.thumbnailImageUrl?
294
487
  .absoluteString as Any,
488
+ "isDefaultImage": user.kakaoAccount?.profile?.isDefaultImage as Any,
295
489
  "phoneNumber": user.kakaoAccount?.phoneNumber as Any,
296
490
  "ageRange": user.kakaoAccount?.ageRange?.rawValue as Any,
297
491
  "birthday": user.kakaoAccount?.birthday as Any,
298
- "birthdayType": user.kakaoAccount?.birthdayType as Any,
492
+ "birthdayType": user.kakaoAccount?.birthdayType?.rawValue as Any,
493
+ "isLeapMonth": user.kakaoAccount?.isLeapMonth as Any,
299
494
  "birthyear": user.kakaoAccount?.birthyear as Any,
300
495
  "gender": user.kakaoAccount?.gender?.rawValue as Any,
301
496
  "isEmailValid": user.kakaoAccount?.isEmailValid as Any,
@@ -313,7 +508,12 @@ import RNCKakaoCore
313
508
  "profileImageNeedsAgreement": user.kakaoAccount?.profileImageNeedsAgreement as Any,
314
509
  "profileNicknameNeedsAgreement": user.kakaoAccount?
315
510
  .profileNicknameNeedsAgreement as Any,
316
- "legalBirthDateNeedsAgreement": user.kakaoAccount?.legalBirthDateNeedsAgreement as Any
511
+ "legalName": user.kakaoAccount?.legalName as Any,
512
+ "legalNameNeedsAgreement": user.kakaoAccount?.legalNameNeedsAgreement as Any,
513
+ "legalBirthDate": user.kakaoAccount?.legalBirthDate as Any,
514
+ "legalBirthDateNeedsAgreement": user.kakaoAccount?.legalBirthDateNeedsAgreement as Any,
515
+ "legalGender": user.kakaoAccount?.legalGender?.rawValue as Any,
516
+ "legalGenderNeedsAgreement": user.kakaoAccount?.legalGenderNeedsAgreement as Any
317
517
  ])
318
518
  } else {
319
519
  RNCKakaoUtil.reject(reject, RNCKakaoError.responseNotFound(name: "user"))
@@ -343,6 +543,55 @@ import RNCKakaoCore
343
543
  }
344
544
  }
345
545
 
546
+ private func mapScopes(_ scopes: [Scope]?) -> [[String: Any]] {
547
+ (scopes ?? []).map { scope in
548
+ [
549
+ "id": scope.id,
550
+ "displayName": scope.displayName,
551
+ "type": scope.type.rawValue,
552
+ "using": scope.using,
553
+ "delegated": scope.delegated as Any,
554
+ "agreed": scope.agreed,
555
+ "revocable": scope.revocable as Any
556
+ ]
557
+ }
558
+ }
559
+
560
+ private func loginLaunchMethod(_ value: String) -> LaunchMethod {
561
+ value == "CustomScheme" ? .CustomScheme : .UniversalLink
562
+ }
563
+
564
+ private func loginPrompts(_ prompts: [String]) -> [Prompt] {
565
+ prompts
566
+ .compactMap { Prompt(rawValue: $0 == "SelectAccount" ? "select_account" : $0.lowercased()) }
567
+ }
568
+
569
+ private func tokenCallback(
570
+ _ resolve: @escaping RCTPromiseResolveBlock,
571
+ reject: @escaping RCTPromiseRejectBlock
572
+ ) -> (OAuthToken?, Error?) -> Void {
573
+ { (token: OAuthToken?, error: Error?) in
574
+ if let error {
575
+ RNCKakaoUtil.reject(reject, error)
576
+ } else if let token {
577
+ let now = Date()
578
+ resolve([
579
+ "accessToken": token.accessToken,
580
+ "refreshToken": token.refreshToken,
581
+ "tokenType": token.tokenType,
582
+ "idToken": token.idToken as Any,
583
+ "accessTokenExpiresAt": token.expiredAt.timeIntervalSince1970,
584
+ "refreshTokenExpiresAt": token.refreshTokenExpiredAt.timeIntervalSince1970,
585
+ "accessTokenExpiresIn": Int(token.expiredAt.timeIntervalSince(now)),
586
+ "refreshTokenExpiresIn": Int(token.refreshTokenExpiredAt.timeIntervalSince(now)),
587
+ "scopes": token.scopes ?? []
588
+ ])
589
+ } else {
590
+ RNCKakaoUtil.reject(reject, RNCKakaoError.responseNotFound(name: "token"))
591
+ }
592
+ }
593
+ }
594
+
346
595
  private func emptyArrayToNil<T>(_ arr: [T]?) -> [T]? {
347
596
  if arr == nil || arr?.isEmpty == true {
348
597
  return nil