b5-api-client 0.0.23 → 0.0.24
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/dist/FirebaseLoginService.d.ts +76 -0
- package/dist/FirebaseLoginService.js +456 -0
- package/dist/UserContext.d.ts +20 -0
- package/dist/UserContext.js +26 -0
- package/dist/auth/FirebaseLoginService.d.ts +76 -0
- package/dist/auth/FirebaseLoginService.js +456 -0
- package/dist/auth/LoginService.d.ts +21 -0
- package/dist/auth/LoginService.js +12 -0
- package/dist/auth/UserContext.d.ts +20 -0
- package/dist/auth/UserContext.js +26 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +7 -1
- package/package.json +3 -2
- package/src/FirebaseLoginService.ts +496 -0
- package/src/auth/FirebaseLoginService.ts +496 -0
- package/src/auth/LoginService.ts +35 -0
- package/src/auth/UserContext.ts +41 -0
- package/src/index.ts +4 -1
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { User } from "firebase/auth";
|
|
2
|
+
import { KioscoinUser } from "./types";
|
|
3
|
+
import P2PMarketplaceAPIClient from "./P2PMarketplaceAPIClient";
|
|
4
|
+
import { FirebaseLoginServiceConfig, LoginService } from "./auth/LoginService";
|
|
5
|
+
export declare enum AuthProvider {
|
|
6
|
+
EMAIL = "EMAIL",
|
|
7
|
+
GOOGLE = "GOOGLE",
|
|
8
|
+
FACEBOOK = "FACEBOOK",
|
|
9
|
+
TWITTER = "TWITTER"
|
|
10
|
+
}
|
|
11
|
+
export declare class AuthState {
|
|
12
|
+
readonly isAuthenticated: boolean;
|
|
13
|
+
readonly user: UserData | null;
|
|
14
|
+
readonly provider: AuthProvider | null;
|
|
15
|
+
private constructor();
|
|
16
|
+
static authenticated(user: UserData, provider: AuthProvider): AuthState;
|
|
17
|
+
static unauthenticated(): AuthState;
|
|
18
|
+
}
|
|
19
|
+
export declare class UserData {
|
|
20
|
+
readonly id: string;
|
|
21
|
+
readonly email: string;
|
|
22
|
+
readonly username: string;
|
|
23
|
+
readonly isEmailVerified: boolean;
|
|
24
|
+
readonly idToken: string | null;
|
|
25
|
+
private constructor();
|
|
26
|
+
static create(id: string, email: string, username: string, isEmailVerified: boolean, idToken: string | null): UserData;
|
|
27
|
+
withEmailVerified(): UserData;
|
|
28
|
+
}
|
|
29
|
+
export declare class AuthResult {
|
|
30
|
+
readonly success: boolean;
|
|
31
|
+
readonly user: KioscoinUser | null;
|
|
32
|
+
readonly userData: UserData | null;
|
|
33
|
+
readonly error: string | null;
|
|
34
|
+
readonly provider: AuthProvider | null;
|
|
35
|
+
private constructor();
|
|
36
|
+
static success(user: KioscoinUser, userData: UserData, provider: AuthProvider): AuthResult;
|
|
37
|
+
static failure(error: string): AuthResult;
|
|
38
|
+
}
|
|
39
|
+
export interface FirebaseConfig {
|
|
40
|
+
apiKey: string;
|
|
41
|
+
authDomain: string;
|
|
42
|
+
projectId: string;
|
|
43
|
+
storageBucket: string;
|
|
44
|
+
messagingSenderId: string;
|
|
45
|
+
appId: string;
|
|
46
|
+
measurementId?: string;
|
|
47
|
+
}
|
|
48
|
+
export declare class FirebaseUnifiedService implements LoginService {
|
|
49
|
+
private app;
|
|
50
|
+
private messaging;
|
|
51
|
+
private auth;
|
|
52
|
+
private readonly actionCodeSettings;
|
|
53
|
+
private client;
|
|
54
|
+
constructor(client: P2PMarketplaceAPIClient, config?: FirebaseLoginServiceConfig);
|
|
55
|
+
private initializeFirebase;
|
|
56
|
+
private fetchFirebaseConfig;
|
|
57
|
+
requestNotificationPermission(): Promise<string | null>;
|
|
58
|
+
fetchToken(): Promise<string | null>;
|
|
59
|
+
onMessageListener(callback: (payload: any) => void): void;
|
|
60
|
+
signInWithEmail(email: string, password: string): Promise<AuthResult>;
|
|
61
|
+
createUserWithEmail(email: string, password: string, username: string): Promise<AuthResult>;
|
|
62
|
+
signInWithGoogle(): Promise<AuthResult>;
|
|
63
|
+
signInWithFacebook(): Promise<AuthResult>;
|
|
64
|
+
signInWithTwitter(): Promise<AuthResult>;
|
|
65
|
+
sendEmailVerification(): Promise<boolean>;
|
|
66
|
+
sendPasswordResetEmail(email: string): Promise<boolean>;
|
|
67
|
+
signOut(): Promise<void>;
|
|
68
|
+
getCurrentUser(): User | null;
|
|
69
|
+
sendSignInLinkToEmail(email: string): Promise<boolean>;
|
|
70
|
+
isSignInWithEmailLink(): boolean;
|
|
71
|
+
signInWithEmailLink(email: string): Promise<AuthResult>;
|
|
72
|
+
getEmailForSignIn(): string | null;
|
|
73
|
+
private _createSuccessAuthResult;
|
|
74
|
+
private getUserFromBackend;
|
|
75
|
+
private createUserInBackend;
|
|
76
|
+
}
|
|
@@ -0,0 +1,456 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.FirebaseUnifiedService = exports.AuthResult = exports.UserData = exports.AuthState = exports.AuthProvider = void 0;
|
|
13
|
+
const app_1 = require("firebase/app");
|
|
14
|
+
const auth_1 = require("firebase/auth");
|
|
15
|
+
const messaging_1 = require("firebase/messaging");
|
|
16
|
+
const UserContext_1 = require("./auth/UserContext");
|
|
17
|
+
// Auth provider type for better type safety
|
|
18
|
+
var AuthProvider;
|
|
19
|
+
(function (AuthProvider) {
|
|
20
|
+
AuthProvider["EMAIL"] = "EMAIL";
|
|
21
|
+
AuthProvider["GOOGLE"] = "GOOGLE";
|
|
22
|
+
AuthProvider["FACEBOOK"] = "FACEBOOK";
|
|
23
|
+
AuthProvider["TWITTER"] = "TWITTER";
|
|
24
|
+
})(AuthProvider = exports.AuthProvider || (exports.AuthProvider = {}));
|
|
25
|
+
// Immutable auth state class
|
|
26
|
+
class AuthState {
|
|
27
|
+
constructor(isAuthenticated, user, provider) {
|
|
28
|
+
this.isAuthenticated = isAuthenticated;
|
|
29
|
+
this.user = user;
|
|
30
|
+
this.provider = provider;
|
|
31
|
+
}
|
|
32
|
+
static authenticated(user, provider) {
|
|
33
|
+
return new AuthState(true, user, provider);
|
|
34
|
+
}
|
|
35
|
+
static unauthenticated() {
|
|
36
|
+
return new AuthState(false, null, null);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
exports.AuthState = AuthState;
|
|
40
|
+
// Enhanced UserData class with additional safety
|
|
41
|
+
class UserData {
|
|
42
|
+
constructor(id, email, username, isEmailVerified, idToken) {
|
|
43
|
+
this.id = id;
|
|
44
|
+
this.email = email;
|
|
45
|
+
this.username = username;
|
|
46
|
+
this.isEmailVerified = isEmailVerified;
|
|
47
|
+
this.idToken = idToken;
|
|
48
|
+
}
|
|
49
|
+
static create(id, email, username, isEmailVerified, idToken) {
|
|
50
|
+
return new UserData(id, email, username, isEmailVerified, idToken);
|
|
51
|
+
}
|
|
52
|
+
withEmailVerified() {
|
|
53
|
+
return new UserData(this.id, this.email, this.username, true, this.idToken);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
exports.UserData = UserData;
|
|
57
|
+
// Enhanced AuthResult class
|
|
58
|
+
class AuthResult {
|
|
59
|
+
constructor(success, user, userData, error, provider) {
|
|
60
|
+
this.success = success;
|
|
61
|
+
this.user = user;
|
|
62
|
+
this.userData = userData;
|
|
63
|
+
this.error = error;
|
|
64
|
+
this.provider = provider;
|
|
65
|
+
}
|
|
66
|
+
static success(user, userData, provider) {
|
|
67
|
+
return new AuthResult(true, user, userData, null, provider);
|
|
68
|
+
}
|
|
69
|
+
static failure(error) {
|
|
70
|
+
return new AuthResult(false, null, null, error, null);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
exports.AuthResult = AuthResult;
|
|
74
|
+
class FirebaseUnifiedService {
|
|
75
|
+
constructor(client, config) {
|
|
76
|
+
var _a;
|
|
77
|
+
this.app = null;
|
|
78
|
+
this.messaging = null;
|
|
79
|
+
this.auth = null;
|
|
80
|
+
this.client = client;
|
|
81
|
+
this.actionCodeSettings = (_a = config === null || config === void 0 ? void 0 : config.actionCodeSettings) !== null && _a !== void 0 ? _a : {
|
|
82
|
+
url: 'http://localhost:3000/auth/verify-email',
|
|
83
|
+
handleCodeInApp: true,
|
|
84
|
+
};
|
|
85
|
+
this.initializeFirebase();
|
|
86
|
+
}
|
|
87
|
+
initializeFirebase() {
|
|
88
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
89
|
+
try {
|
|
90
|
+
const firebaseConfig = yield this.fetchFirebaseConfig();
|
|
91
|
+
this.app = (0, app_1.initializeApp)(firebaseConfig);
|
|
92
|
+
this.auth = (0, auth_1.getAuth)(this.app);
|
|
93
|
+
}
|
|
94
|
+
catch (error) {
|
|
95
|
+
console.error("Failed to initialize Firebase app:", error);
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
fetchFirebaseConfig() {
|
|
100
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
101
|
+
try {
|
|
102
|
+
const response = yield this.client.getConfig();
|
|
103
|
+
return response.config.firebase;
|
|
104
|
+
}
|
|
105
|
+
catch (error) {
|
|
106
|
+
console.error("Error fetching Firebase configuration:", error);
|
|
107
|
+
throw new Error("Failed to initialize Firebase configuration");
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
// Messaging methods
|
|
112
|
+
requestNotificationPermission() {
|
|
113
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
114
|
+
if (!this.app) {
|
|
115
|
+
yield this.initializeFirebase();
|
|
116
|
+
}
|
|
117
|
+
if (!this.messaging) {
|
|
118
|
+
console.warn("Messaging is not available");
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
121
|
+
try {
|
|
122
|
+
const permission = yield Notification.requestPermission();
|
|
123
|
+
if (permission === "granted") {
|
|
124
|
+
const token = yield (0, messaging_1.getToken)(this.messaging, {
|
|
125
|
+
vapidKey: process.env.REACT_APP_FIREBASE_VAPID_KEY,
|
|
126
|
+
});
|
|
127
|
+
return token;
|
|
128
|
+
}
|
|
129
|
+
return null;
|
|
130
|
+
}
|
|
131
|
+
catch (error) {
|
|
132
|
+
console.error("Failed to get notification token:", error);
|
|
133
|
+
return null;
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
fetchToken() {
|
|
138
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
139
|
+
try {
|
|
140
|
+
if (!this.messaging && this.app) {
|
|
141
|
+
this.messaging = (0, messaging_1.getMessaging)(this.app);
|
|
142
|
+
}
|
|
143
|
+
if (this.messaging) {
|
|
144
|
+
const currentToken = yield (0, messaging_1.getToken)(this.messaging);
|
|
145
|
+
return currentToken;
|
|
146
|
+
}
|
|
147
|
+
return null;
|
|
148
|
+
}
|
|
149
|
+
catch (error) {
|
|
150
|
+
console.error("An error occurred while retrieving token. ", error);
|
|
151
|
+
return null;
|
|
152
|
+
}
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
onMessageListener(callback) {
|
|
156
|
+
if (!this.messaging && this.app) {
|
|
157
|
+
this.messaging = (0, messaging_1.getMessaging)(this.app);
|
|
158
|
+
}
|
|
159
|
+
if (this.messaging) {
|
|
160
|
+
(0, messaging_1.onMessage)(this.messaging, callback);
|
|
161
|
+
}
|
|
162
|
+
else {
|
|
163
|
+
console.error("Messaging is not initialized.");
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
// Authentication methods
|
|
167
|
+
signInWithEmail(email, password) {
|
|
168
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
169
|
+
try {
|
|
170
|
+
if (!this.auth) {
|
|
171
|
+
console.error("Firebase Auth not initialized");
|
|
172
|
+
return AuthResult.failure("Firebase Auth not initialized");
|
|
173
|
+
}
|
|
174
|
+
const userCredential = yield (0, auth_1.signInWithEmailAndPassword)(this.auth, email, password);
|
|
175
|
+
const idToken = yield userCredential.user.getIdToken();
|
|
176
|
+
const backendUser = yield this.getUserFromBackend(userCredential.user.uid, idToken);
|
|
177
|
+
if (backendUser) {
|
|
178
|
+
const authResult = this._createSuccessAuthResult(userCredential.user, backendUser, AuthProvider.EMAIL, idToken);
|
|
179
|
+
// Update UserContext
|
|
180
|
+
UserContext_1.userContext.setUser({
|
|
181
|
+
id: userCredential.user.uid,
|
|
182
|
+
username: backendUser.username || '',
|
|
183
|
+
email: userCredential.user.email || '',
|
|
184
|
+
idToken: idToken
|
|
185
|
+
});
|
|
186
|
+
return authResult;
|
|
187
|
+
}
|
|
188
|
+
else {
|
|
189
|
+
return AuthResult.failure('User not found in backend');
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
catch (error) {
|
|
193
|
+
console.error('Detailed error signing in with email:', {
|
|
194
|
+
code: error.code,
|
|
195
|
+
message: error.message,
|
|
196
|
+
fullError: error
|
|
197
|
+
});
|
|
198
|
+
return AuthResult.failure(error.message || 'Authentication failed');
|
|
199
|
+
}
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
createUserWithEmail(email, password, username) {
|
|
203
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
204
|
+
try {
|
|
205
|
+
if (!this.auth) {
|
|
206
|
+
return AuthResult.failure("Firebase Auth not initialized");
|
|
207
|
+
}
|
|
208
|
+
// First create the user in Firebase
|
|
209
|
+
const userCredential = yield (0, auth_1.createUserWithEmailAndPassword)(this.auth, email, password);
|
|
210
|
+
const user = userCredential.user;
|
|
211
|
+
const idToken = yield user.getIdToken();
|
|
212
|
+
// Send email verification
|
|
213
|
+
yield (0, auth_1.sendEmailVerification)(user);
|
|
214
|
+
const backendUser = yield this.createUserInBackend(user.uid, username, idToken);
|
|
215
|
+
if (backendUser) {
|
|
216
|
+
return this._createSuccessAuthResult(user, backendUser, AuthProvider.EMAIL, idToken);
|
|
217
|
+
}
|
|
218
|
+
else {
|
|
219
|
+
return AuthResult.failure('Failed to create user in backend');
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
catch (error) {
|
|
223
|
+
console.error('Error creating user with email:', error);
|
|
224
|
+
return AuthResult.failure(error.message || 'User creation failed');
|
|
225
|
+
}
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
signInWithGoogle() {
|
|
229
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
230
|
+
try {
|
|
231
|
+
if (!this.auth) {
|
|
232
|
+
return AuthResult.failure("Firebase Auth not initialized");
|
|
233
|
+
}
|
|
234
|
+
const provider = new auth_1.GoogleAuthProvider();
|
|
235
|
+
const userCredential = yield (0, auth_1.signInWithPopup)(this.auth, provider);
|
|
236
|
+
const user = userCredential.user;
|
|
237
|
+
// Get or create user in your Kotlin backend
|
|
238
|
+
const backendUser = yield this.getUserFromBackend(user.uid, user.displayName || '');
|
|
239
|
+
const idToken = yield user.getIdToken();
|
|
240
|
+
if (backendUser) {
|
|
241
|
+
// Use the new helper method
|
|
242
|
+
return this._createSuccessAuthResult(user, backendUser, AuthProvider.GOOGLE, idToken);
|
|
243
|
+
}
|
|
244
|
+
else {
|
|
245
|
+
return AuthResult.failure('Failed to get or create user in backend');
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
catch (error) {
|
|
249
|
+
console.error('Error signing in with Google:', error);
|
|
250
|
+
return AuthResult.failure(error.message || 'Google authentication failed');
|
|
251
|
+
}
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
signInWithFacebook() {
|
|
255
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
256
|
+
try {
|
|
257
|
+
if (!this.auth) {
|
|
258
|
+
return AuthResult.failure("Firebase Auth not initialized");
|
|
259
|
+
}
|
|
260
|
+
const provider = new auth_1.FacebookAuthProvider();
|
|
261
|
+
const userCredential = yield (0, auth_1.signInWithPopup)(this.auth, provider);
|
|
262
|
+
const user = userCredential.user;
|
|
263
|
+
// Get or create user in your Kotlin backend
|
|
264
|
+
const backendUser = yield this.getUserFromBackend(user.uid, user.displayName || '');
|
|
265
|
+
const idToken = yield user.getIdToken();
|
|
266
|
+
if (backendUser) {
|
|
267
|
+
// Use the new helper method
|
|
268
|
+
return this._createSuccessAuthResult(user, backendUser, AuthProvider.FACEBOOK, idToken);
|
|
269
|
+
}
|
|
270
|
+
else {
|
|
271
|
+
return AuthResult.failure('Failed to get or create user in backend');
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
catch (error) {
|
|
275
|
+
console.error('Error signing in with Facebook:', error);
|
|
276
|
+
return AuthResult.failure(error.message || 'Facebook authentication failed');
|
|
277
|
+
}
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
signInWithTwitter() {
|
|
281
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
282
|
+
try {
|
|
283
|
+
if (!this.auth) {
|
|
284
|
+
return AuthResult.failure("Firebase Auth not initialized");
|
|
285
|
+
}
|
|
286
|
+
const provider = new auth_1.TwitterAuthProvider();
|
|
287
|
+
const userCredential = yield (0, auth_1.signInWithPopup)(this.auth, provider);
|
|
288
|
+
const user = userCredential.user;
|
|
289
|
+
// Get or create user in your Kotlin backend
|
|
290
|
+
const backendUser = yield this.getUserFromBackend(user.uid, user.displayName || '');
|
|
291
|
+
const idToken = yield user.getIdToken();
|
|
292
|
+
if (backendUser) {
|
|
293
|
+
// Use the new helper method
|
|
294
|
+
return this._createSuccessAuthResult(user, backendUser, AuthProvider.TWITTER, idToken);
|
|
295
|
+
}
|
|
296
|
+
else {
|
|
297
|
+
return AuthResult.failure('Failed to get or create user in backend');
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
catch (error) {
|
|
301
|
+
console.error('Error signing in with Twitter:', error);
|
|
302
|
+
return AuthResult.failure(error.message || 'Twitter authentication failed');
|
|
303
|
+
}
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
sendEmailVerification() {
|
|
307
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
308
|
+
try {
|
|
309
|
+
if (!this.auth) {
|
|
310
|
+
return false;
|
|
311
|
+
}
|
|
312
|
+
const user = this.auth.currentUser;
|
|
313
|
+
if (user) {
|
|
314
|
+
yield (0, auth_1.sendEmailVerification)(user);
|
|
315
|
+
return true;
|
|
316
|
+
}
|
|
317
|
+
return false;
|
|
318
|
+
}
|
|
319
|
+
catch (error) {
|
|
320
|
+
console.error('Error sending email verification:', error);
|
|
321
|
+
return false;
|
|
322
|
+
}
|
|
323
|
+
});
|
|
324
|
+
}
|
|
325
|
+
sendPasswordResetEmail(email) {
|
|
326
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
327
|
+
try {
|
|
328
|
+
if (!this.auth) {
|
|
329
|
+
return false;
|
|
330
|
+
}
|
|
331
|
+
yield (0, auth_1.sendPasswordResetEmail)(this.auth, email);
|
|
332
|
+
return true;
|
|
333
|
+
}
|
|
334
|
+
catch (error) {
|
|
335
|
+
console.error('Error sending password reset email:', error);
|
|
336
|
+
return false;
|
|
337
|
+
}
|
|
338
|
+
});
|
|
339
|
+
}
|
|
340
|
+
signOut() {
|
|
341
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
342
|
+
try {
|
|
343
|
+
if (!this.auth) {
|
|
344
|
+
return;
|
|
345
|
+
}
|
|
346
|
+
yield (0, auth_1.signOut)(this.auth);
|
|
347
|
+
// Clear UserContext
|
|
348
|
+
UserContext_1.userContext.clearUser();
|
|
349
|
+
}
|
|
350
|
+
catch (error) {
|
|
351
|
+
console.error('Error signing out:', error);
|
|
352
|
+
}
|
|
353
|
+
});
|
|
354
|
+
}
|
|
355
|
+
getCurrentUser() {
|
|
356
|
+
if (!this.auth) {
|
|
357
|
+
return null;
|
|
358
|
+
}
|
|
359
|
+
return this.auth.currentUser;
|
|
360
|
+
}
|
|
361
|
+
sendSignInLinkToEmail(email) {
|
|
362
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
363
|
+
try {
|
|
364
|
+
if (!this.auth) {
|
|
365
|
+
return false;
|
|
366
|
+
}
|
|
367
|
+
yield (0, auth_1.sendSignInLinkToEmail)(this.auth, email, this.actionCodeSettings);
|
|
368
|
+
// Save the email locally to use it later when the user clicks the link
|
|
369
|
+
window.localStorage.setItem('emailForSignIn', email);
|
|
370
|
+
return true;
|
|
371
|
+
}
|
|
372
|
+
catch (error) {
|
|
373
|
+
console.error('Error sending sign-in link to email:', error);
|
|
374
|
+
return false;
|
|
375
|
+
}
|
|
376
|
+
});
|
|
377
|
+
}
|
|
378
|
+
isSignInWithEmailLink() {
|
|
379
|
+
if (!this.auth) {
|
|
380
|
+
return false;
|
|
381
|
+
}
|
|
382
|
+
return (0, auth_1.isSignInWithEmailLink)(this.auth, window.location.href);
|
|
383
|
+
}
|
|
384
|
+
signInWithEmailLink(email) {
|
|
385
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
386
|
+
try {
|
|
387
|
+
if (!this.auth) {
|
|
388
|
+
return AuthResult.failure("Firebase Auth not initialized");
|
|
389
|
+
}
|
|
390
|
+
if (!this.isSignInWithEmailLink()) {
|
|
391
|
+
return AuthResult.failure("Invalid sign-in link");
|
|
392
|
+
}
|
|
393
|
+
const userCredential = yield (0, auth_1.signInWithEmailLink)(this.auth, email, window.location.href);
|
|
394
|
+
const user = userCredential.user;
|
|
395
|
+
// Clear the email from localStorage
|
|
396
|
+
window.localStorage.removeItem('emailForSignIn');
|
|
397
|
+
// Get or create user in your Kotlin backend
|
|
398
|
+
const backendUser = yield this.getUserFromBackend(user.uid, user.displayName || '');
|
|
399
|
+
const idToken = yield user.getIdToken();
|
|
400
|
+
if (backendUser) {
|
|
401
|
+
// Use the new helper method
|
|
402
|
+
return this._createSuccessAuthResult(user, backendUser, AuthProvider.EMAIL, idToken);
|
|
403
|
+
}
|
|
404
|
+
else {
|
|
405
|
+
return AuthResult.failure('Failed to get or create user in backend');
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
catch (error) {
|
|
409
|
+
console.error('Error signing in with email link:', error);
|
|
410
|
+
return AuthResult.failure(error.message || 'Email link authentication failed');
|
|
411
|
+
}
|
|
412
|
+
});
|
|
413
|
+
}
|
|
414
|
+
getEmailForSignIn() {
|
|
415
|
+
return window.localStorage.getItem('emailForSignIn');
|
|
416
|
+
}
|
|
417
|
+
// Helper method to create success AuthResult
|
|
418
|
+
_createSuccessAuthResult(user, backendUser, provider, idToken) {
|
|
419
|
+
const userData = UserData.create(user.uid, user.email || '', backendUser.username || '', user.emailVerified, idToken);
|
|
420
|
+
return AuthResult.success(backendUser, userData, provider);
|
|
421
|
+
}
|
|
422
|
+
// Backend integration methods
|
|
423
|
+
getUserFromBackend(userId, loginId) {
|
|
424
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
425
|
+
try {
|
|
426
|
+
const response = yield this.client.getUser(userId, {
|
|
427
|
+
Authorization: `Bearer ${loginId}`,
|
|
428
|
+
});
|
|
429
|
+
return response.users[0];
|
|
430
|
+
}
|
|
431
|
+
catch (error) {
|
|
432
|
+
console.error('Error getting user from backend:', error);
|
|
433
|
+
return null;
|
|
434
|
+
}
|
|
435
|
+
});
|
|
436
|
+
}
|
|
437
|
+
createUserInBackend(userId, username, idToken) {
|
|
438
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
439
|
+
try {
|
|
440
|
+
const createUserRequest = {
|
|
441
|
+
id: userId,
|
|
442
|
+
username: username
|
|
443
|
+
};
|
|
444
|
+
const response = yield this.client.createUser(createUserRequest, {
|
|
445
|
+
Authorization: `Bearer ${idToken}`
|
|
446
|
+
});
|
|
447
|
+
return response.users[0];
|
|
448
|
+
}
|
|
449
|
+
catch (error) {
|
|
450
|
+
console.error('Error creating user in backend:', error);
|
|
451
|
+
return null;
|
|
452
|
+
}
|
|
453
|
+
});
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
exports.FirebaseUnifiedService = FirebaseUnifiedService;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export interface User {
|
|
2
|
+
id: string;
|
|
3
|
+
username: string;
|
|
4
|
+
email: string;
|
|
5
|
+
idToken: string;
|
|
6
|
+
}
|
|
7
|
+
export interface UserContext {
|
|
8
|
+
user: User | null;
|
|
9
|
+
setUser: (user: User | null) => void;
|
|
10
|
+
updateUser: (updates: Partial<User>) => void;
|
|
11
|
+
clearUser: () => void;
|
|
12
|
+
}
|
|
13
|
+
export declare class UserContextImpl implements UserContext {
|
|
14
|
+
private _user;
|
|
15
|
+
get user(): User | null;
|
|
16
|
+
setUser(user: User | null): void;
|
|
17
|
+
updateUser(updates: Partial<User>): void;
|
|
18
|
+
clearUser(): void;
|
|
19
|
+
}
|
|
20
|
+
export declare const userContext: UserContextImpl;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.userContext = exports.UserContextImpl = void 0;
|
|
4
|
+
// Implement the UserContext class
|
|
5
|
+
class UserContextImpl {
|
|
6
|
+
constructor() {
|
|
7
|
+
this._user = null;
|
|
8
|
+
}
|
|
9
|
+
get user() {
|
|
10
|
+
return this._user;
|
|
11
|
+
}
|
|
12
|
+
setUser(user) {
|
|
13
|
+
this._user = user;
|
|
14
|
+
}
|
|
15
|
+
updateUser(updates) {
|
|
16
|
+
if (this._user) {
|
|
17
|
+
this._user = Object.assign(Object.assign({}, this._user), updates);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
clearUser() {
|
|
21
|
+
this._user = null;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
exports.UserContextImpl = UserContextImpl;
|
|
25
|
+
// Singleton instance of UserContext
|
|
26
|
+
exports.userContext = new UserContextImpl();
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { User } from "firebase/auth";
|
|
2
|
+
import { KioscoinUser } from "../types";
|
|
3
|
+
import P2PMarketplaceAPIClient from "../P2PMarketplaceAPIClient";
|
|
4
|
+
import { FirebaseLoginServiceConfig, LoginService } from "./LoginService";
|
|
5
|
+
export declare enum AuthProvider {
|
|
6
|
+
EMAIL = "EMAIL",
|
|
7
|
+
GOOGLE = "GOOGLE",
|
|
8
|
+
FACEBOOK = "FACEBOOK",
|
|
9
|
+
TWITTER = "TWITTER"
|
|
10
|
+
}
|
|
11
|
+
export declare class AuthState {
|
|
12
|
+
readonly isAuthenticated: boolean;
|
|
13
|
+
readonly user: UserData | null;
|
|
14
|
+
readonly provider: AuthProvider | null;
|
|
15
|
+
private constructor();
|
|
16
|
+
static authenticated(user: UserData, provider: AuthProvider): AuthState;
|
|
17
|
+
static unauthenticated(): AuthState;
|
|
18
|
+
}
|
|
19
|
+
export declare class UserData {
|
|
20
|
+
readonly id: string;
|
|
21
|
+
readonly email: string;
|
|
22
|
+
readonly username: string;
|
|
23
|
+
readonly isEmailVerified: boolean;
|
|
24
|
+
readonly idToken: string | null;
|
|
25
|
+
private constructor();
|
|
26
|
+
static create(id: string, email: string, username: string, isEmailVerified: boolean, idToken: string | null): UserData;
|
|
27
|
+
withEmailVerified(): UserData;
|
|
28
|
+
}
|
|
29
|
+
export declare class AuthResult {
|
|
30
|
+
readonly success: boolean;
|
|
31
|
+
readonly user: KioscoinUser | null;
|
|
32
|
+
readonly userData: UserData | null;
|
|
33
|
+
readonly error: string | null;
|
|
34
|
+
readonly provider: AuthProvider | null;
|
|
35
|
+
private constructor();
|
|
36
|
+
static success(user: KioscoinUser, userData: UserData, provider: AuthProvider): AuthResult;
|
|
37
|
+
static failure(error: string): AuthResult;
|
|
38
|
+
}
|
|
39
|
+
export interface FirebaseConfig {
|
|
40
|
+
apiKey: string;
|
|
41
|
+
authDomain: string;
|
|
42
|
+
projectId: string;
|
|
43
|
+
storageBucket: string;
|
|
44
|
+
messagingSenderId: string;
|
|
45
|
+
appId: string;
|
|
46
|
+
measurementId?: string;
|
|
47
|
+
}
|
|
48
|
+
export declare class FirebaseUnifiedService implements LoginService {
|
|
49
|
+
private app;
|
|
50
|
+
private messaging;
|
|
51
|
+
private auth;
|
|
52
|
+
private readonly actionCodeSettings;
|
|
53
|
+
private client;
|
|
54
|
+
constructor(client: P2PMarketplaceAPIClient, config?: FirebaseLoginServiceConfig);
|
|
55
|
+
private initializeFirebase;
|
|
56
|
+
private fetchFirebaseConfig;
|
|
57
|
+
requestNotificationPermission(): Promise<string | null>;
|
|
58
|
+
fetchToken(): Promise<string | null>;
|
|
59
|
+
onMessageListener(callback: (payload: any) => void): void;
|
|
60
|
+
signInWithEmail(email: string, password: string): Promise<AuthResult>;
|
|
61
|
+
createUserWithEmail(email: string, password: string, username: string): Promise<AuthResult>;
|
|
62
|
+
signInWithGoogle(): Promise<AuthResult>;
|
|
63
|
+
signInWithFacebook(): Promise<AuthResult>;
|
|
64
|
+
signInWithTwitter(): Promise<AuthResult>;
|
|
65
|
+
sendEmailVerification(): Promise<boolean>;
|
|
66
|
+
sendPasswordResetEmail(email: string): Promise<boolean>;
|
|
67
|
+
signOut(): Promise<void>;
|
|
68
|
+
getCurrentUser(): User | null;
|
|
69
|
+
sendSignInLinkToEmail(email: string): Promise<boolean>;
|
|
70
|
+
isSignInWithEmailLink(): boolean;
|
|
71
|
+
signInWithEmailLink(email: string): Promise<AuthResult>;
|
|
72
|
+
getEmailForSignIn(): string | null;
|
|
73
|
+
private _createSuccessAuthResult;
|
|
74
|
+
private getUserFromBackend;
|
|
75
|
+
private createUserInBackend;
|
|
76
|
+
}
|