react-native-nitro-auth 0.6.2 → 0.6.4
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 +20 -62
- package/README.md +50 -11
- package/android/src/main/java/com/auth/AuthAdapter.kt +5 -5
- package/ios/AuthAdapter.swift +18 -12
- package/lib/commonjs/Auth.web.js +75 -63
- package/lib/commonjs/Auth.web.js.map +1 -1
- package/lib/commonjs/ui/social-button.js +39 -31
- package/lib/commonjs/ui/social-button.js.map +1 -1
- package/lib/module/Auth.web.js +75 -63
- package/lib/module/Auth.web.js.map +1 -1
- package/lib/module/ui/social-button.js +40 -31
- package/lib/module/ui/social-button.js.map +1 -1
- package/lib/typescript/commonjs/Auth.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/social-button.d.ts +1 -1
- package/lib/typescript/commonjs/ui/social-button.d.ts.map +1 -1
- package/lib/typescript/module/Auth.web.d.ts.map +1 -1
- package/lib/typescript/module/ui/social-button.d.ts +1 -1
- package/lib/typescript/module/ui/social-button.d.ts.map +1 -1
- package/package.json +19 -2
- package/src/Auth.web.ts +143 -67
- package/src/ui/social-button.tsx +46 -38
package/src/Auth.web.ts
CHANGED
|
@@ -86,9 +86,12 @@ type AuthWebExtraConfig = {
|
|
|
86
86
|
};
|
|
87
87
|
|
|
88
88
|
type JsonObject = Record<string, unknown>;
|
|
89
|
+
type AppleAuthInitConfig = Parameters<
|
|
90
|
+
NonNullable<Window["AppleID"]>["auth"]["init"]
|
|
91
|
+
>[0];
|
|
89
92
|
|
|
90
93
|
class AuthWebError extends Error {
|
|
91
|
-
public readonly underlyingError
|
|
94
|
+
public readonly underlyingError: string | undefined;
|
|
92
95
|
|
|
93
96
|
constructor(message: AuthErrorCode, underlyingError?: string) {
|
|
94
97
|
super(message);
|
|
@@ -121,6 +124,29 @@ const getOptionalNumber = (
|
|
|
121
124
|
: undefined;
|
|
122
125
|
};
|
|
123
126
|
|
|
127
|
+
function setIfDefined<T extends object, K extends keyof T>(
|
|
128
|
+
target: T,
|
|
129
|
+
key: K,
|
|
130
|
+
value: T[K] | undefined,
|
|
131
|
+
): void {
|
|
132
|
+
if (value !== undefined) {
|
|
133
|
+
target[key] = value;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function setOrDelete<T extends object, K extends keyof T>(
|
|
138
|
+
target: T,
|
|
139
|
+
key: K,
|
|
140
|
+
value: T[K] | undefined,
|
|
141
|
+
): void {
|
|
142
|
+
if (value === undefined) {
|
|
143
|
+
delete target[key];
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
target[key] = value;
|
|
148
|
+
}
|
|
149
|
+
|
|
124
150
|
const parseExpiresInSeconds = (value: unknown): number | undefined => {
|
|
125
151
|
const candidate =
|
|
126
152
|
typeof value === "number"
|
|
@@ -152,19 +178,32 @@ const parseAuthUser = (value: unknown): AuthUser | undefined => {
|
|
|
152
178
|
)
|
|
153
179
|
: undefined;
|
|
154
180
|
|
|
155
|
-
|
|
181
|
+
const user: AuthUser = {
|
|
156
182
|
provider: value.provider,
|
|
157
|
-
email: getOptionalString(value, "email"),
|
|
158
|
-
name: getOptionalString(value, "name"),
|
|
159
|
-
photo: getOptionalString(value, "photo"),
|
|
160
|
-
idToken: getOptionalString(value, "idToken"),
|
|
161
|
-
accessToken: getOptionalString(value, "accessToken"),
|
|
162
|
-
refreshToken: getOptionalString(value, "refreshToken"),
|
|
163
|
-
serverAuthCode: getOptionalString(value, "serverAuthCode"),
|
|
164
|
-
scopes,
|
|
165
|
-
expirationTime: getOptionalNumber(value, "expirationTime"),
|
|
166
|
-
underlyingError: getOptionalString(value, "underlyingError"),
|
|
167
183
|
};
|
|
184
|
+
setIfDefined(user, "email", getOptionalString(value, "email"));
|
|
185
|
+
setIfDefined(user, "name", getOptionalString(value, "name"));
|
|
186
|
+
setIfDefined(user, "photo", getOptionalString(value, "photo"));
|
|
187
|
+
setIfDefined(user, "idToken", getOptionalString(value, "idToken"));
|
|
188
|
+
setIfDefined(user, "accessToken", getOptionalString(value, "accessToken"));
|
|
189
|
+
setIfDefined(user, "refreshToken", getOptionalString(value, "refreshToken"));
|
|
190
|
+
setIfDefined(
|
|
191
|
+
user,
|
|
192
|
+
"serverAuthCode",
|
|
193
|
+
getOptionalString(value, "serverAuthCode"),
|
|
194
|
+
);
|
|
195
|
+
setIfDefined(user, "scopes", scopes);
|
|
196
|
+
setIfDefined(
|
|
197
|
+
user,
|
|
198
|
+
"expirationTime",
|
|
199
|
+
getOptionalNumber(value, "expirationTime"),
|
|
200
|
+
);
|
|
201
|
+
setIfDefined(
|
|
202
|
+
user,
|
|
203
|
+
"underlyingError",
|
|
204
|
+
getOptionalString(value, "underlyingError"),
|
|
205
|
+
);
|
|
206
|
+
return user;
|
|
168
207
|
};
|
|
169
208
|
|
|
170
209
|
const parseScopes = (value: unknown): string[] | undefined => {
|
|
@@ -191,18 +230,41 @@ const parseAuthWebExtraConfig = (value: unknown): AuthWebExtraConfig => {
|
|
|
191
230
|
? nitroAuthWebStorageCandidate
|
|
192
231
|
: undefined;
|
|
193
232
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
233
|
+
const config: AuthWebExtraConfig = {};
|
|
234
|
+
setIfDefined(
|
|
235
|
+
config,
|
|
236
|
+
"googleWebClientId",
|
|
237
|
+
getOptionalString(value, "googleWebClientId"),
|
|
238
|
+
);
|
|
239
|
+
setIfDefined(
|
|
240
|
+
config,
|
|
241
|
+
"microsoftClientId",
|
|
242
|
+
getOptionalString(value, "microsoftClientId"),
|
|
243
|
+
);
|
|
244
|
+
setIfDefined(
|
|
245
|
+
config,
|
|
246
|
+
"microsoftTenant",
|
|
247
|
+
getOptionalString(value, "microsoftTenant"),
|
|
248
|
+
);
|
|
249
|
+
setIfDefined(
|
|
250
|
+
config,
|
|
251
|
+
"microsoftB2cDomain",
|
|
252
|
+
getOptionalString(value, "microsoftB2cDomain"),
|
|
253
|
+
);
|
|
254
|
+
setIfDefined(
|
|
255
|
+
config,
|
|
256
|
+
"appleWebClientId",
|
|
257
|
+
getOptionalString(value, "appleWebClientId"),
|
|
258
|
+
);
|
|
259
|
+
setIfDefined(config, "nitroAuthWebStorage", nitroAuthWebStorage);
|
|
260
|
+
setIfDefined(
|
|
261
|
+
config,
|
|
262
|
+
"nitroAuthPersistTokensOnWeb",
|
|
263
|
+
typeof value.nitroAuthPersistTokensOnWeb === "boolean"
|
|
264
|
+
? value.nitroAuthPersistTokensOnWeb
|
|
265
|
+
: undefined,
|
|
266
|
+
);
|
|
267
|
+
return config;
|
|
206
268
|
};
|
|
207
269
|
|
|
208
270
|
const getConfig = (): AuthWebExtraConfig => {
|
|
@@ -723,20 +785,23 @@ class AuthWeb implements Auth {
|
|
|
723
785
|
: {};
|
|
724
786
|
const user: AuthUser = {
|
|
725
787
|
...currentUser,
|
|
726
|
-
idToken: effectiveIdToken,
|
|
727
|
-
accessToken: accessToken ?? undefined,
|
|
728
|
-
refreshToken: newRefreshToken ?? currentUser.refreshToken,
|
|
729
|
-
expirationTime,
|
|
730
788
|
...claims,
|
|
731
789
|
};
|
|
790
|
+
setOrDelete(user, "idToken", effectiveIdToken);
|
|
791
|
+
setOrDelete(user, "accessToken", accessToken);
|
|
792
|
+
setOrDelete(
|
|
793
|
+
user,
|
|
794
|
+
"refreshToken",
|
|
795
|
+
newRefreshToken ?? currentUser.refreshToken,
|
|
796
|
+
);
|
|
797
|
+
setOrDelete(user, "expirationTime", expirationTime);
|
|
732
798
|
this.updateUser(user);
|
|
733
799
|
|
|
734
|
-
const tokens: AuthTokens = {
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
};
|
|
800
|
+
const tokens: AuthTokens = {};
|
|
801
|
+
setIfDefined(tokens, "accessToken", accessToken);
|
|
802
|
+
setIfDefined(tokens, "idToken", effectiveIdToken);
|
|
803
|
+
setIfDefined(tokens, "refreshToken", newRefreshToken);
|
|
804
|
+
setIfDefined(tokens, "expirationTime", expirationTime);
|
|
740
805
|
this.notifyTokenListeners(tokens);
|
|
741
806
|
return tokens;
|
|
742
807
|
}
|
|
@@ -757,12 +822,11 @@ class AuthWeb implements Auth {
|
|
|
757
822
|
),
|
|
758
823
|
);
|
|
759
824
|
this.assertActiveGeneration(generation);
|
|
760
|
-
const tokens: AuthTokens = {
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
};
|
|
825
|
+
const tokens: AuthTokens = {};
|
|
826
|
+
setIfDefined(tokens, "accessToken", this._currentUser.accessToken);
|
|
827
|
+
setIfDefined(tokens, "idToken", this._currentUser.idToken);
|
|
828
|
+
setIfDefined(tokens, "refreshToken", this._currentUser.refreshToken);
|
|
829
|
+
setIfDefined(tokens, "expirationTime", this._currentUser.expirationTime);
|
|
766
830
|
this.notifyTokenListeners(tokens);
|
|
767
831
|
return tokens;
|
|
768
832
|
}
|
|
@@ -1084,14 +1148,14 @@ class AuthWeb implements Auth {
|
|
|
1084
1148
|
const user: AuthUser = {
|
|
1085
1149
|
provider: "google",
|
|
1086
1150
|
idToken,
|
|
1087
|
-
accessToken: accessToken ?? undefined,
|
|
1088
|
-
serverAuthCode: code ?? undefined,
|
|
1089
|
-
userId: getOptionalString(decoded, "sub"),
|
|
1090
|
-
hostedDomain: getOptionalString(decoded, "hd"),
|
|
1091
1151
|
scopes,
|
|
1092
|
-
expirationTime: this.getExpirationTime(expiresIn),
|
|
1093
1152
|
...this.decodeGoogleJwt(idToken),
|
|
1094
1153
|
};
|
|
1154
|
+
setIfDefined(user, "accessToken", accessToken ?? undefined);
|
|
1155
|
+
setIfDefined(user, "serverAuthCode", code ?? undefined);
|
|
1156
|
+
setIfDefined(user, "userId", getOptionalString(decoded, "sub"));
|
|
1157
|
+
setIfDefined(user, "hostedDomain", getOptionalString(decoded, "hd"));
|
|
1158
|
+
setIfDefined(user, "expirationTime", this.getExpirationTime(expiresIn));
|
|
1095
1159
|
this.updateUser(user);
|
|
1096
1160
|
})
|
|
1097
1161
|
.then(() => {
|
|
@@ -1106,13 +1170,13 @@ class AuthWeb implements Auth {
|
|
|
1106
1170
|
private decodeGoogleJwt(token: string): Partial<AuthUser> {
|
|
1107
1171
|
try {
|
|
1108
1172
|
const decoded = this.parseJwtPayload(token);
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1173
|
+
const user: Partial<AuthUser> = {};
|
|
1174
|
+
setIfDefined(user, "email", getOptionalString(decoded, "email"));
|
|
1175
|
+
setIfDefined(user, "name", getOptionalString(decoded, "name"));
|
|
1176
|
+
setIfDefined(user, "photo", getOptionalString(decoded, "picture"));
|
|
1177
|
+
setIfDefined(user, "userId", getOptionalString(decoded, "sub"));
|
|
1178
|
+
setIfDefined(user, "hostedDomain", getOptionalString(decoded, "hd"));
|
|
1179
|
+
return user;
|
|
1116
1180
|
} catch (error) {
|
|
1117
1181
|
logger.warn("Failed to decode Google ID token", { error: String(error) });
|
|
1118
1182
|
return {};
|
|
@@ -1328,12 +1392,16 @@ class AuthWeb implements Auth {
|
|
|
1328
1392
|
const user: AuthUser = {
|
|
1329
1393
|
provider: "microsoft",
|
|
1330
1394
|
idToken,
|
|
1331
|
-
accessToken: accessToken ?? undefined,
|
|
1332
|
-
refreshToken: refreshToken ?? undefined,
|
|
1333
1395
|
scopes,
|
|
1334
|
-
expirationTime: this.getExpirationTime(json["expires_in"]),
|
|
1335
1396
|
...claims,
|
|
1336
1397
|
};
|
|
1398
|
+
setIfDefined(user, "accessToken", accessToken);
|
|
1399
|
+
setIfDefined(user, "refreshToken", refreshToken);
|
|
1400
|
+
setIfDefined(
|
|
1401
|
+
user,
|
|
1402
|
+
"expirationTime",
|
|
1403
|
+
this.getExpirationTime(json["expires_in"]),
|
|
1404
|
+
);
|
|
1337
1405
|
this.updateUser(user);
|
|
1338
1406
|
}
|
|
1339
1407
|
|
|
@@ -1405,12 +1473,15 @@ class AuthWeb implements Auth {
|
|
|
1405
1473
|
private decodeMicrosoftJwt(token: string): Partial<AuthUser> {
|
|
1406
1474
|
try {
|
|
1407
1475
|
const decoded = this.parseJwtPayload(token);
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1476
|
+
const user: Partial<AuthUser> = {};
|
|
1477
|
+
setIfDefined(
|
|
1478
|
+
user,
|
|
1479
|
+
"email",
|
|
1480
|
+
getOptionalString(decoded, "preferred_username") ??
|
|
1411
1481
|
getOptionalString(decoded, "email"),
|
|
1412
|
-
|
|
1413
|
-
|
|
1482
|
+
);
|
|
1483
|
+
setIfDefined(user, "name", getOptionalString(decoded, "name"));
|
|
1484
|
+
return user;
|
|
1414
1485
|
} catch (error) {
|
|
1415
1486
|
logger.warn("Failed to decode Microsoft ID token", {
|
|
1416
1487
|
error: String(error),
|
|
@@ -1495,16 +1566,17 @@ class AuthWeb implements Auth {
|
|
|
1495
1566
|
throw new Error("Apple SDK not loaded");
|
|
1496
1567
|
}
|
|
1497
1568
|
|
|
1498
|
-
|
|
1569
|
+
const appleAuthConfig: AppleAuthInitConfig = {
|
|
1499
1570
|
clientId,
|
|
1500
1571
|
scope: (options?.scopes?.length
|
|
1501
1572
|
? options.scopes
|
|
1502
1573
|
: ["name", "email"]
|
|
1503
1574
|
).join(" "),
|
|
1504
1575
|
redirectURI: window.location.origin,
|
|
1505
|
-
nonce: options?.nonce,
|
|
1506
1576
|
usePopup: true,
|
|
1507
|
-
}
|
|
1577
|
+
};
|
|
1578
|
+
setIfDefined(appleAuthConfig, "nonce", options?.nonce);
|
|
1579
|
+
window.AppleID.auth.init(appleAuthConfig);
|
|
1508
1580
|
|
|
1509
1581
|
try {
|
|
1510
1582
|
const response: AppleAuthResponse = await window.AppleID.auth.signIn();
|
|
@@ -1514,12 +1586,16 @@ class AuthWeb implements Auth {
|
|
|
1514
1586
|
const user: AuthUser = {
|
|
1515
1587
|
provider: "apple",
|
|
1516
1588
|
idToken: response.authorization.id_token,
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1589
|
+
};
|
|
1590
|
+
setIfDefined(user, "authorizationCode", response.authorization.code);
|
|
1591
|
+
setIfDefined(user, "email", response.user?.email);
|
|
1592
|
+
setIfDefined(
|
|
1593
|
+
user,
|
|
1594
|
+
"name",
|
|
1595
|
+
response.user?.name
|
|
1520
1596
|
? `${response.user.name.firstName} ${response.user.name.lastName}`.trim()
|
|
1521
1597
|
: undefined,
|
|
1522
|
-
|
|
1598
|
+
);
|
|
1523
1599
|
this.updateUser(user);
|
|
1524
1600
|
} catch (error) {
|
|
1525
1601
|
throw this.mapError(error);
|
package/src/ui/social-button.tsx
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useState } from "react";
|
|
1
|
+
import React, { useCallback, useMemo, useState } from "react";
|
|
2
2
|
import type { ViewStyle, TextStyle } from "react-native";
|
|
3
3
|
import {
|
|
4
4
|
Pressable,
|
|
@@ -34,7 +34,7 @@ const PROVIDER_LABELS: Record<AuthProvider, string> = {
|
|
|
34
34
|
const PROVIDER_PRIMARY_BACKGROUND: Record<AuthProvider, string> = {
|
|
35
35
|
google: "#4285F4",
|
|
36
36
|
apple: "#000000",
|
|
37
|
-
microsoft: "#
|
|
37
|
+
microsoft: "#1f2937",
|
|
38
38
|
};
|
|
39
39
|
|
|
40
40
|
const getBackgroundColor = ({
|
|
@@ -46,21 +46,29 @@ const getBackgroundColor = ({
|
|
|
46
46
|
variant: SocialButtonVariant;
|
|
47
47
|
provider: AuthProvider;
|
|
48
48
|
}): string => {
|
|
49
|
-
if (disabled) return "#
|
|
49
|
+
if (disabled) return "#E2E8F0";
|
|
50
50
|
if (variant === "black") return "#000000";
|
|
51
51
|
if (variant === "white") return "#FFFFFF";
|
|
52
52
|
if (variant === "outline") return "transparent";
|
|
53
53
|
return PROVIDER_PRIMARY_BACKGROUND[provider];
|
|
54
54
|
};
|
|
55
55
|
|
|
56
|
-
const getTextColor = (
|
|
57
|
-
|
|
56
|
+
const getTextColor = ({
|
|
57
|
+
disabled,
|
|
58
|
+
variant,
|
|
59
|
+
}: {
|
|
60
|
+
disabled: boolean;
|
|
61
|
+
variant: SocialButtonVariant;
|
|
62
|
+
}): string => {
|
|
63
|
+
if (disabled) return "#64748B";
|
|
64
|
+
return variant === "white" || variant === "outline" ? "#111827" : "#FFFFFF";
|
|
65
|
+
};
|
|
58
66
|
|
|
59
67
|
async function performLogin(provider: AuthProvider): Promise<void> {
|
|
60
68
|
await AuthService.login(provider);
|
|
61
69
|
}
|
|
62
70
|
|
|
63
|
-
export const SocialButton = ({
|
|
71
|
+
export const SocialButton = React.memo(function SocialButton({
|
|
64
72
|
provider,
|
|
65
73
|
variant = "primary",
|
|
66
74
|
borderRadius = 8,
|
|
@@ -70,10 +78,11 @@ export const SocialButton = ({
|
|
|
70
78
|
onSuccess,
|
|
71
79
|
onError,
|
|
72
80
|
onPress,
|
|
73
|
-
}: SocialButtonProps)
|
|
81
|
+
}: SocialButtonProps) {
|
|
74
82
|
const [loading, setLoading] = useState(false);
|
|
83
|
+
const isDisabled = loading || disabled === true;
|
|
75
84
|
|
|
76
|
-
const handleLogin = async () => {
|
|
85
|
+
const handleLogin = useCallback(async () => {
|
|
77
86
|
if (loading || disabled) return;
|
|
78
87
|
if (onPress) {
|
|
79
88
|
onPress();
|
|
@@ -96,36 +105,41 @@ export const SocialButton = ({
|
|
|
96
105
|
} finally {
|
|
97
106
|
setLoading(false);
|
|
98
107
|
}
|
|
99
|
-
};
|
|
100
|
-
const isDisabled = loading || disabled === true;
|
|
108
|
+
}, [disabled, loading, onError, onPress, onSuccess, provider]);
|
|
101
109
|
|
|
102
|
-
const
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
110
|
+
const buttonStyle = useMemo(
|
|
111
|
+
() => ({
|
|
112
|
+
backgroundColor: getBackgroundColor({
|
|
113
|
+
disabled: isDisabled,
|
|
114
|
+
variant,
|
|
115
|
+
provider,
|
|
116
|
+
}),
|
|
117
|
+
borderRadius,
|
|
118
|
+
borderColor: variant === "outline" ? "#DDDDDD" : "transparent",
|
|
119
|
+
borderWidth: variant === "outline" ? 1 : 0,
|
|
120
|
+
}),
|
|
121
|
+
[borderRadius, isDisabled, provider, variant],
|
|
122
|
+
);
|
|
123
|
+
|
|
124
|
+
const textColor = getTextColor({ disabled: isDisabled, variant });
|
|
125
|
+
const labelStyle = useMemo(
|
|
126
|
+
() => [styles.text, { color: textColor }, textStyle],
|
|
127
|
+
[textColor, textStyle],
|
|
128
|
+
);
|
|
129
|
+
const appleIconStyle = useMemo(
|
|
130
|
+
() => [styles.iconText, { color: textColor }],
|
|
131
|
+
[textColor],
|
|
132
|
+
);
|
|
106
133
|
|
|
107
134
|
return (
|
|
108
135
|
<Pressable
|
|
109
|
-
style={[
|
|
110
|
-
styles.button,
|
|
111
|
-
{
|
|
112
|
-
backgroundColor: getBackgroundColor({
|
|
113
|
-
disabled: isDisabled,
|
|
114
|
-
variant,
|
|
115
|
-
provider,
|
|
116
|
-
}),
|
|
117
|
-
borderRadius,
|
|
118
|
-
borderColor: getBorderColor(),
|
|
119
|
-
borderWidth: variant === "outline" ? 1 : 0,
|
|
120
|
-
},
|
|
121
|
-
style,
|
|
122
|
-
]}
|
|
136
|
+
style={[styles.button, buttonStyle, style]}
|
|
123
137
|
onPress={handleLogin}
|
|
124
138
|
disabled={isDisabled}
|
|
125
139
|
>
|
|
126
140
|
<View style={styles.content}>
|
|
127
141
|
{loading ? (
|
|
128
|
-
<ActivityIndicator size="small" color={
|
|
142
|
+
<ActivityIndicator size="small" color={textColor} />
|
|
129
143
|
) : (
|
|
130
144
|
<>
|
|
131
145
|
{provider === "google" && variant !== "primary" && (
|
|
@@ -135,11 +149,7 @@ export const SocialButton = ({
|
|
|
135
149
|
)}
|
|
136
150
|
{provider === "apple" && variant !== "primary" && (
|
|
137
151
|
<View style={styles.iconPlaceholder}>
|
|
138
|
-
<Text
|
|
139
|
-
style={[styles.iconText, { color: getTextColor(variant) }]}
|
|
140
|
-
>
|
|
141
|
-
|
|
142
|
-
</Text>
|
|
152
|
+
<Text style={appleIconStyle}></Text>
|
|
143
153
|
</View>
|
|
144
154
|
)}
|
|
145
155
|
{provider === "microsoft" && variant !== "primary" && (
|
|
@@ -147,9 +157,7 @@ export const SocialButton = ({
|
|
|
147
157
|
<Text style={styles.microsoftIconText}>⊞</Text>
|
|
148
158
|
</View>
|
|
149
159
|
)}
|
|
150
|
-
<Text
|
|
151
|
-
style={[styles.text, { color: getTextColor(variant) }, textStyle]}
|
|
152
|
-
>
|
|
160
|
+
<Text style={labelStyle}>
|
|
153
161
|
Sign in with {PROVIDER_LABELS[provider]}
|
|
154
162
|
</Text>
|
|
155
163
|
</>
|
|
@@ -157,7 +165,7 @@ export const SocialButton = ({
|
|
|
157
165
|
</View>
|
|
158
166
|
</Pressable>
|
|
159
167
|
);
|
|
160
|
-
};
|
|
168
|
+
});
|
|
161
169
|
|
|
162
170
|
const styles = StyleSheet.create({
|
|
163
171
|
button: {
|