@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.
- package/CHANGELOG.md +107 -0
- package/android/src/main/java/net/mjstudio/rnkakao/user/RNCKakaoUserModule.kt +450 -204
- package/ios/RNCKakaoUser.mm +84 -11
- package/ios/RNCKakaoUserManager.swift +319 -70
- package/lib/commonjs/index.js +121 -16
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/index.web.js +200 -25
- package/lib/commonjs/index.web.js.map +1 -1
- package/lib/commonjs/spec/NativeKakaoUser.ts +35 -4
- package/lib/commonjs/validateShippingAddressOptions.js +20 -0
- package/lib/commonjs/validateShippingAddressOptions.js.map +1 -0
- package/lib/module/index.js +113 -17
- package/lib/module/index.js.map +1 -1
- package/lib/module/index.web.js +190 -25
- package/lib/module/index.web.js.map +1 -1
- package/lib/module/spec/NativeKakaoUser.ts +35 -4
- package/lib/module/validateShippingAddressOptions.js +16 -0
- package/lib/module/validateShippingAddressOptions.js.map +1 -0
- package/lib/typescript/src/index.d.ts +109 -27
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/spec/NativeKakaoUser.d.ts +15 -6
- package/lib/typescript/src/spec/NativeKakaoUser.d.ts.map +1 -1
- package/lib/typescript/src/validateShippingAddressOptions.d.ts +6 -0
- package/lib/typescript/src/validateShippingAddressOptions.d.ts.map +1 -0
- package/package.json +5 -5
- package/src/index.ts +251 -39
- package/src/index.web.ts +232 -37
- package/src/spec/NativeKakaoUser.ts +35 -4
- package/src/validateShippingAddressOptions.ts +30 -0
package/src/index.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { is } from '@mj-studio/js-util';
|
|
2
|
-
import { kAssert } from '@react-native-kakao/core';
|
|
2
|
+
import { kAssert, kCreateWebError } from '@react-native-kakao/core';
|
|
3
3
|
|
|
4
4
|
import Native from './spec/NativeKakaoUser';
|
|
5
|
+
import { validateShippingAddressOptions } from './validateShippingAddressOptions';
|
|
5
6
|
|
|
6
7
|
export interface KakaoLoginToken {
|
|
7
8
|
accessToken: string;
|
|
@@ -14,13 +15,28 @@ export interface KakaoLoginToken {
|
|
|
14
15
|
refreshTokenExpiresIn: number;
|
|
15
16
|
scopes: string[];
|
|
16
17
|
}
|
|
18
|
+
export type KakaoCodeTokenOptions = {
|
|
19
|
+
code: string;
|
|
20
|
+
codeVerifier?: string;
|
|
21
|
+
redirectUri?: string;
|
|
22
|
+
web?: { clientSecret?: string };
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const minActivityRequestCode = -2147483648;
|
|
26
|
+
const maxActivityRequestCode = 2147483647;
|
|
27
|
+
|
|
28
|
+
export type KakaoTalkLaunchMethod = 'UniversalLink' | 'CustomScheme';
|
|
29
|
+
|
|
30
|
+
const defaultTalkLaunchMethod: KakaoTalkLaunchMethod = 'UniversalLink';
|
|
31
|
+
const webOnlyErrorCode = 'Package-UnsupportedPlatform';
|
|
32
|
+
|
|
17
33
|
export interface KakaoScopeInfo {
|
|
18
34
|
id: string;
|
|
19
35
|
agreed: boolean;
|
|
20
36
|
displayName: string;
|
|
21
|
-
revocable?: boolean;
|
|
37
|
+
revocable?: boolean | null;
|
|
22
38
|
using: boolean;
|
|
23
|
-
delegated?: boolean;
|
|
39
|
+
delegated?: boolean | null;
|
|
24
40
|
type: string;
|
|
25
41
|
}
|
|
26
42
|
export interface KakaoServiceTerms {
|
|
@@ -29,7 +45,12 @@ export interface KakaoServiceTerms {
|
|
|
29
45
|
agreed: boolean;
|
|
30
46
|
required: boolean;
|
|
31
47
|
revocable: boolean;
|
|
48
|
+
agreedBy?: 'KAUTH' | 'KAPI' | 'unknown';
|
|
32
49
|
}
|
|
50
|
+
export type KakaoRevokedServiceTerms = {
|
|
51
|
+
tag: string;
|
|
52
|
+
agreed: boolean;
|
|
53
|
+
};
|
|
33
54
|
export interface KakaoAppServiceTerms {
|
|
34
55
|
tag: string;
|
|
35
56
|
createdAt: number;
|
|
@@ -56,34 +77,45 @@ export interface KakaoShippingAddress {
|
|
|
56
77
|
}
|
|
57
78
|
export interface KakaoUser {
|
|
58
79
|
id: number;
|
|
59
|
-
|
|
80
|
+
properties: Record<string, string>;
|
|
81
|
+
hasSignedUp?: boolean | null;
|
|
82
|
+
uuid?: string | null;
|
|
83
|
+
groupUserToken?: string | null;
|
|
84
|
+
email?: string | null;
|
|
60
85
|
name?: string | null;
|
|
61
|
-
nickname
|
|
62
|
-
profileImageUrl
|
|
63
|
-
thumbnailImageUrl
|
|
86
|
+
nickname?: string | null;
|
|
87
|
+
profileImageUrl?: string | null;
|
|
88
|
+
thumbnailImageUrl?: string | null;
|
|
89
|
+
isDefaultImage?: boolean | null;
|
|
64
90
|
phoneNumber?: string | null;
|
|
65
91
|
ageRange?: string | null;
|
|
66
92
|
birthday?: string | null;
|
|
67
93
|
birthdayType?: string | null;
|
|
94
|
+
isLeapMonth?: boolean | null;
|
|
68
95
|
birthyear?: string | null;
|
|
69
96
|
gender?: string | null;
|
|
70
|
-
isEmailValid
|
|
71
|
-
isEmailVerified
|
|
72
|
-
isKorean?: boolean;
|
|
73
|
-
ageRangeNeedsAgreement?: boolean;
|
|
74
|
-
birthdayNeedsAgreement?: boolean;
|
|
75
|
-
birthyearNeedsAgreement?: boolean;
|
|
76
|
-
emailNeedsAgreement?: boolean;
|
|
77
|
-
genderNeedsAgreement?: boolean;
|
|
78
|
-
isKoreanNeedsAgreement?: boolean;
|
|
79
|
-
phoneNumberNeedsAgreement?: boolean;
|
|
80
|
-
profileNeedsAgreement?: boolean;
|
|
81
|
-
nameNeedsAgreement?: boolean;
|
|
82
|
-
profileImageNeedsAgreement?: boolean;
|
|
83
|
-
profileNicknameNeedsAgreement?: boolean;
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
97
|
+
isEmailValid?: boolean | null;
|
|
98
|
+
isEmailVerified?: boolean | null;
|
|
99
|
+
isKorean?: boolean | null;
|
|
100
|
+
ageRangeNeedsAgreement?: boolean | null;
|
|
101
|
+
birthdayNeedsAgreement?: boolean | null;
|
|
102
|
+
birthyearNeedsAgreement?: boolean | null;
|
|
103
|
+
emailNeedsAgreement?: boolean | null;
|
|
104
|
+
genderNeedsAgreement?: boolean | null;
|
|
105
|
+
isKoreanNeedsAgreement?: boolean | null;
|
|
106
|
+
phoneNumberNeedsAgreement?: boolean | null;
|
|
107
|
+
profileNeedsAgreement?: boolean | null;
|
|
108
|
+
nameNeedsAgreement?: boolean | null;
|
|
109
|
+
profileImageNeedsAgreement?: boolean | null;
|
|
110
|
+
profileNicknameNeedsAgreement?: boolean | null;
|
|
111
|
+
legalName?: string | null;
|
|
112
|
+
legalNameNeedsAgreement?: boolean | null;
|
|
113
|
+
legalBirthDate?: string | null;
|
|
114
|
+
legalBirthDateNeedsAgreement?: boolean | null;
|
|
115
|
+
legalGender?: 'female' | 'male' | null;
|
|
116
|
+
legalGenderNeedsAgreement?: boolean | null;
|
|
117
|
+
connectedAt?: number | null;
|
|
118
|
+
synchedAt?: number | null;
|
|
87
119
|
}
|
|
88
120
|
export interface KakaoAccessTokenInfo {
|
|
89
121
|
id?: number;
|
|
@@ -96,12 +128,20 @@ export function login({
|
|
|
96
128
|
useKakaoAccountLogin,
|
|
97
129
|
scopes,
|
|
98
130
|
nonce,
|
|
131
|
+
loginHint,
|
|
132
|
+
channelPublicIds,
|
|
133
|
+
android,
|
|
134
|
+
ios,
|
|
99
135
|
}: {
|
|
100
136
|
serviceTerms?: string[];
|
|
101
137
|
prompts?: ('Login' | 'Create' | 'Cert' | 'SelectAccount')[];
|
|
102
138
|
scopes?: string[];
|
|
103
139
|
useKakaoAccountLogin?: boolean;
|
|
104
140
|
nonce?: string;
|
|
141
|
+
loginHint?: string;
|
|
142
|
+
channelPublicIds?: string[];
|
|
143
|
+
android?: { requestCode?: number };
|
|
144
|
+
ios?: { launchMethod?: KakaoTalkLaunchMethod };
|
|
105
145
|
web?: {
|
|
106
146
|
redirectUri: string;
|
|
107
147
|
scope?: string[];
|
|
@@ -113,37 +153,141 @@ export function login({
|
|
|
113
153
|
nonce?: string;
|
|
114
154
|
};
|
|
115
155
|
} = {}): Promise<KakaoLoginToken> {
|
|
156
|
+
const requestCode = android?.requestCode;
|
|
157
|
+
kAssert(
|
|
158
|
+
requestCode == null ||
|
|
159
|
+
(Number.isInteger(requestCode) &&
|
|
160
|
+
requestCode >= minActivityRequestCode &&
|
|
161
|
+
requestCode <= maxActivityRequestCode),
|
|
162
|
+
`[login] android.requestCode must be an integer from ${minActivityRequestCode} to ${maxActivityRequestCode}`,
|
|
163
|
+
);
|
|
164
|
+
|
|
116
165
|
kAssert(
|
|
117
166
|
!useKakaoAccountLogin ? !is.notEmptyArray(prompts) && !is.notEmptyArray(scopes) : true,
|
|
118
167
|
'[login] `prompts` and `scopes` cannot be passed if useKakaoAccountLogin is false.',
|
|
119
168
|
);
|
|
120
169
|
|
|
121
170
|
kAssert(
|
|
122
|
-
is.notEmptyArray(scopes)
|
|
123
|
-
|
|
171
|
+
is.notEmptyArray(scopes)
|
|
172
|
+
? !is.notEmptyArray(prompts) &&
|
|
173
|
+
!is.notEmptyArray(serviceTerms) &&
|
|
174
|
+
!is.notEmptyArray(channelPublicIds)
|
|
175
|
+
: true,
|
|
176
|
+
'[login] `scopes` cannot be passed with `prompts`, `serviceTerms`, or `channelPublicIds`',
|
|
177
|
+
);
|
|
178
|
+
|
|
179
|
+
kAssert(
|
|
180
|
+
loginHint == null ||
|
|
181
|
+
(!is.notEmptyArray(scopes) &&
|
|
182
|
+
!is.notEmptyArray(serviceTerms) &&
|
|
183
|
+
!is.notEmptyArray(channelPublicIds)),
|
|
184
|
+
'[login] `loginHint` cannot be passed with `scopes`, `serviceTerms`, or `channelPublicIds` on native platforms.',
|
|
124
185
|
);
|
|
125
186
|
|
|
126
187
|
return Native.login(
|
|
127
188
|
serviceTerms ?? [],
|
|
128
189
|
prompts ?? [],
|
|
129
190
|
useKakaoAccountLogin ?? false,
|
|
191
|
+
ios?.launchMethod ?? defaultTalkLaunchMethod,
|
|
130
192
|
scopes ?? [],
|
|
131
193
|
nonce,
|
|
194
|
+
loginHint,
|
|
195
|
+
channelPublicIds ?? [],
|
|
196
|
+
requestCode,
|
|
197
|
+
);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
export async function signup({ properties }: { properties?: Record<string, string> } = {}) {
|
|
201
|
+
await Native.signup(properties);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
export function loginWithKakao({
|
|
205
|
+
uiMode = 'auto',
|
|
206
|
+
prompts,
|
|
207
|
+
loginHint,
|
|
208
|
+
nonce,
|
|
209
|
+
channelPublicIds,
|
|
210
|
+
serviceTerms,
|
|
211
|
+
ios,
|
|
212
|
+
}: {
|
|
213
|
+
uiMode?: 'auto' | 'light' | 'dark';
|
|
214
|
+
prompts?: ('Login' | 'Create' | 'Cert' | 'SelectAccount')[];
|
|
215
|
+
loginHint?: string;
|
|
216
|
+
nonce?: string;
|
|
217
|
+
channelPublicIds?: string[];
|
|
218
|
+
serviceTerms?: string[];
|
|
219
|
+
ios?: {
|
|
220
|
+
orientation?: 'auto' | 'portrait' | 'landscape';
|
|
221
|
+
launchMethod?: KakaoTalkLaunchMethod;
|
|
222
|
+
};
|
|
223
|
+
} = {}): Promise<KakaoLoginToken> {
|
|
224
|
+
return Native.loginWithKakao(
|
|
225
|
+
uiMode,
|
|
226
|
+
ios?.orientation ?? 'auto',
|
|
227
|
+
ios?.launchMethod ?? defaultTalkLaunchMethod,
|
|
228
|
+
prompts ?? [],
|
|
229
|
+
loginHint,
|
|
230
|
+
nonce,
|
|
231
|
+
channelPublicIds ?? [],
|
|
232
|
+
serviceTerms ?? [],
|
|
132
233
|
);
|
|
133
234
|
}
|
|
134
235
|
|
|
135
|
-
export function
|
|
136
|
-
|
|
236
|
+
export function refreshToken({
|
|
237
|
+
token,
|
|
238
|
+
ios,
|
|
239
|
+
}: {
|
|
240
|
+
token?: KakaoLoginToken;
|
|
241
|
+
ios?: { loggingEnabled?: boolean };
|
|
242
|
+
} = {}): Promise<KakaoLoginToken> {
|
|
243
|
+
kAssert(
|
|
244
|
+
ios?.loggingEnabled == null || typeof ios.loggingEnabled === 'boolean',
|
|
245
|
+
'[refreshToken] ios.loggingEnabled must be a boolean',
|
|
246
|
+
);
|
|
247
|
+
|
|
248
|
+
if (token !== undefined) {
|
|
249
|
+
kAssert(
|
|
250
|
+
token != null &&
|
|
251
|
+
is.string(token.accessToken) &&
|
|
252
|
+
token.accessToken.length > 0 &&
|
|
253
|
+
is.string(token.refreshToken) &&
|
|
254
|
+
token.refreshToken.length > 0,
|
|
255
|
+
'[refreshToken] token must contain non-empty accessToken and refreshToken strings',
|
|
256
|
+
);
|
|
257
|
+
|
|
258
|
+
kAssert(
|
|
259
|
+
[token.accessTokenExpiresAt, token.refreshTokenExpiresAt].every(
|
|
260
|
+
(value) => Number.isFinite(value) && !Number.isNaN(new Date(value * 1000).getTime()),
|
|
261
|
+
) && [token.accessTokenExpiresIn, token.refreshTokenExpiresIn].every(Number.isFinite),
|
|
262
|
+
'[refreshToken] token expiry timestamps must be valid Unix seconds and lifetimes must be finite',
|
|
263
|
+
);
|
|
264
|
+
|
|
265
|
+
kAssert(
|
|
266
|
+
(token.tokenType == null || is.string(token.tokenType)) &&
|
|
267
|
+
(token.idToken == null || is.string(token.idToken)) &&
|
|
268
|
+
Array.isArray(token.scopes) &&
|
|
269
|
+
token.scopes.every((scope) => is.string(scope)),
|
|
270
|
+
'[refreshToken] tokenType and idToken must be strings when present, and scopes must be strings',
|
|
271
|
+
);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
return Native.refreshToken(token, ios?.loggingEnabled ?? true);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
export async function logout() {
|
|
278
|
+
await Native.logout();
|
|
137
279
|
}
|
|
138
280
|
|
|
139
|
-
export function unlink() {
|
|
140
|
-
|
|
281
|
+
export async function unlink() {
|
|
282
|
+
await Native.unlink();
|
|
141
283
|
}
|
|
142
284
|
|
|
143
285
|
export function isLogined() {
|
|
144
286
|
return Native.isLogined();
|
|
145
287
|
}
|
|
146
288
|
|
|
289
|
+
export const hasToken = Native.hasToken;
|
|
290
|
+
|
|
147
291
|
export function isKakaoTalkLoginAvailable(): Promise<boolean> {
|
|
148
292
|
return Native.isKakaoTalkLoginAvailable();
|
|
149
293
|
}
|
|
@@ -152,33 +296,89 @@ export function scopes(scopes?: string[]): Promise<KakaoScopeInfo[]> {
|
|
|
152
296
|
return Native.scopes(scopes);
|
|
153
297
|
}
|
|
154
298
|
|
|
155
|
-
export function revokeScopes(scopes: string[]): Promise<void> {
|
|
299
|
+
export async function revokeScopes(scopes: string[]): Promise<void> {
|
|
300
|
+
await Native.revokeScopes(scopes);
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
export function revokeScopesWithResult(scopes: string[]): Promise<KakaoScopeInfo[]> {
|
|
156
304
|
return Native.revokeScopes(scopes);
|
|
157
305
|
}
|
|
158
306
|
|
|
159
|
-
export function serviceTerms(
|
|
160
|
-
|
|
307
|
+
export function serviceTerms({
|
|
308
|
+
result,
|
|
309
|
+
tags,
|
|
310
|
+
}: {
|
|
311
|
+
result?: 'agreed_service_terms' | 'app_service_terms';
|
|
312
|
+
tags?: string[];
|
|
313
|
+
} = {}): Promise<KakaoServiceTerms[]> {
|
|
314
|
+
return Native.serviceTerms(result, tags);
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
export async function shippingAddresses({
|
|
318
|
+
addressId,
|
|
319
|
+
fromUpdatedAt,
|
|
320
|
+
pageSize,
|
|
321
|
+
}: {
|
|
322
|
+
addressId?: number;
|
|
323
|
+
fromUpdatedAt?: number;
|
|
324
|
+
pageSize?: number;
|
|
325
|
+
} = {}): Promise<KakaoShippingAddressResult> {
|
|
326
|
+
validateShippingAddressOptions({ addressId, fromUpdatedAt, pageSize });
|
|
327
|
+
|
|
328
|
+
return Native.shippingAddresses(addressId, fromUpdatedAt, pageSize);
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
export function revokeServiceTerms(tags: string[]): Promise<KakaoRevokedServiceTerms[]> {
|
|
332
|
+
return Native.revokeServiceTerms(tags);
|
|
161
333
|
}
|
|
162
334
|
|
|
163
|
-
export function
|
|
164
|
-
return Native.
|
|
335
|
+
export function selectShippingAddress(): Promise<number> {
|
|
336
|
+
return Native.selectShippingAddress();
|
|
165
337
|
}
|
|
166
338
|
|
|
167
|
-
export function me(
|
|
168
|
-
|
|
339
|
+
export function me({
|
|
340
|
+
propertyKeys,
|
|
341
|
+
secureResource = true,
|
|
342
|
+
}: { propertyKeys?: string[]; secureResource?: boolean } = {}): Promise<KakaoUser> {
|
|
343
|
+
return Native.me(propertyKeys, secureResource);
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
export async function issueAccessTokenWithCode({
|
|
347
|
+
code,
|
|
348
|
+
codeVerifier,
|
|
349
|
+
redirectUri,
|
|
350
|
+
}: KakaoCodeTokenOptions): Promise<KakaoLoginToken> {
|
|
351
|
+
kAssert(is.string(code) && code.length > 0, '[issueAccessTokenWithCode] code is required');
|
|
352
|
+
|
|
353
|
+
return Native.issueAccessTokenWithCode(code, codeVerifier, redirectUri);
|
|
169
354
|
}
|
|
170
355
|
|
|
171
356
|
export function getAccessToken(): Promise<KakaoAccessTokenInfo> {
|
|
172
357
|
return Native.getAccessToken();
|
|
173
358
|
}
|
|
174
359
|
|
|
360
|
+
export async function updateProfile({
|
|
361
|
+
properties,
|
|
362
|
+
}: {
|
|
363
|
+
properties: Record<string, string>;
|
|
364
|
+
}): Promise<void> {
|
|
365
|
+
await Native.updateProfile(properties);
|
|
366
|
+
}
|
|
367
|
+
|
|
175
368
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
176
|
-
export function setAccessTokenWeb(token: string) {
|
|
369
|
+
export function setAccessTokenWeb(token: string): void {
|
|
370
|
+
kCreateWebError({
|
|
371
|
+
code: webOnlyErrorCode,
|
|
372
|
+
message: '[setAccessTokenWeb] This API is only supported on web.',
|
|
373
|
+
});
|
|
374
|
+
}
|
|
375
|
+
|
|
177
376
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
178
377
|
export async function issueAccessTokenWithCodeWeb(params: {
|
|
179
378
|
redirectUri: string;
|
|
180
379
|
clientSecret?: string;
|
|
181
380
|
code: string;
|
|
381
|
+
codeVerifier?: string;
|
|
182
382
|
}): Promise<{
|
|
183
383
|
tokenType: string;
|
|
184
384
|
accessToken: string;
|
|
@@ -188,20 +388,32 @@ export async function issueAccessTokenWithCodeWeb(params: {
|
|
|
188
388
|
refreshTokenExpiresIn: number;
|
|
189
389
|
scope?: string;
|
|
190
390
|
}> {
|
|
191
|
-
|
|
391
|
+
kCreateWebError({
|
|
392
|
+
code: webOnlyErrorCode,
|
|
393
|
+
message: '[issueAccessTokenWithCodeWeb] This API is only supported on web.',
|
|
394
|
+
});
|
|
192
395
|
}
|
|
193
396
|
|
|
194
397
|
const KakaoUser = {
|
|
195
398
|
login,
|
|
399
|
+
loginWithKakao,
|
|
400
|
+
refreshToken,
|
|
401
|
+
issueAccessTokenWithCode,
|
|
402
|
+
signup,
|
|
196
403
|
logout,
|
|
197
404
|
unlink,
|
|
198
405
|
isLogined,
|
|
406
|
+
hasToken,
|
|
199
407
|
isKakaoTalkLoginAvailable,
|
|
200
408
|
scopes,
|
|
201
409
|
revokeScopes,
|
|
410
|
+
revokeScopesWithResult,
|
|
202
411
|
serviceTerms,
|
|
412
|
+
revokeServiceTerms,
|
|
203
413
|
shippingAddresses,
|
|
414
|
+
selectShippingAddress,
|
|
204
415
|
me,
|
|
416
|
+
updateProfile,
|
|
205
417
|
getAccessToken,
|
|
206
418
|
setAccessTokenWeb,
|
|
207
419
|
issueAccessTokenWithCodeWeb,
|