@umituz/web-firebase 2.1.1 → 3.0.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/package.json +12 -39
- package/src/domains/auth/entities/index.ts +60 -0
- package/src/domains/auth/index.ts +13 -0
- package/src/domains/auth/services/auth.service.ts +245 -0
- package/src/domains/auth/services/index.ts +7 -0
- package/src/domains/auth/types/auth-service.interface.ts +72 -0
- package/src/domains/auth/types/index.ts +5 -0
- package/src/domains/firestore/entities/index.ts +82 -0
- package/src/domains/firestore/index.ts +13 -0
- package/src/domains/firestore/services/firestore.service.ts +191 -0
- package/src/domains/firestore/services/index.ts +7 -0
- package/src/domains/firestore/types/firestore-service.interface.ts +64 -0
- package/src/domains/firestore/types/index.ts +5 -0
- package/src/domains/storage/entities/index.ts +94 -0
- package/src/domains/storage/index.ts +13 -0
- package/src/domains/storage/services/index.ts +7 -0
- package/src/domains/storage/services/storage.service.ts +223 -0
- package/src/domains/storage/types/index.ts +5 -0
- package/src/domains/storage/types/storage-service.interface.ts +120 -0
- package/src/index.ts +12 -16
- package/src/presentation/hooks/useAuth.ts +69 -26
- package/src/presentation/providers/FirebaseProvider.tsx +9 -14
- package/dist/application/index.d.mts +0 -273
- package/dist/application/index.d.ts +0 -273
- package/dist/application/index.js +0 -490
- package/dist/application/index.mjs +0 -19
- package/dist/chunk-34DL2QWQ.mjs +0 -87
- package/dist/chunk-4FP2ELQ5.mjs +0 -96
- package/dist/chunk-7TX3OU3O.mjs +0 -721
- package/dist/chunk-I6WGBPFB.mjs +0 -439
- package/dist/chunk-RZ4QR6TB.mjs +0 -96
- package/dist/chunk-U2XI4MGO.mjs +0 -397
- package/dist/domain/index.d.mts +0 -325
- package/dist/domain/index.d.ts +0 -325
- package/dist/domain/index.js +0 -662
- package/dist/domain/index.mjs +0 -36
- package/dist/file.repository.interface-v5vHgVsZ.d.mts +0 -241
- package/dist/file.repository.interface-v5vHgVsZ.d.ts +0 -241
- package/dist/firebase.entity-xvfEPjXZ.d.mts +0 -15
- package/dist/firebase.entity-xvfEPjXZ.d.ts +0 -15
- package/dist/index.d.mts +0 -14
- package/dist/index.d.ts +0 -14
- package/dist/index.js +0 -1833
- package/dist/index.mjs +0 -98
- package/dist/infrastructure/index.d.mts +0 -170
- package/dist/infrastructure/index.d.ts +0 -170
- package/dist/infrastructure/index.js +0 -856
- package/dist/infrastructure/index.mjs +0 -46
- package/dist/presentation/index.d.mts +0 -25
- package/dist/presentation/index.d.ts +0 -25
- package/dist/presentation/index.js +0 -105
- package/dist/presentation/index.mjs +0 -6
- package/dist/user.repository.interface-DS74TsJ5.d.mts +0 -298
- package/dist/user.repository.interface-DS74TsJ5.d.ts +0 -298
package/package.json
CHANGED
|
@@ -1,49 +1,25 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@umituz/web-firebase",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "Comprehensive Firebase integration with
|
|
5
|
-
"main": "./
|
|
6
|
-
"
|
|
7
|
-
"types": "./dist/index.d.ts",
|
|
3
|
+
"version": "3.0.0",
|
|
4
|
+
"description": "Comprehensive Firebase integration with domain-based architecture for web applications",
|
|
5
|
+
"main": "./src/index.ts",
|
|
6
|
+
"types": "./src/index.ts",
|
|
8
7
|
"sideEffects": false,
|
|
9
8
|
"publishConfig": {
|
|
10
9
|
"access": "public"
|
|
11
10
|
},
|
|
12
11
|
"exports": {
|
|
13
|
-
".":
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
"./domain": {
|
|
19
|
-
"types": "./dist/domain/index.d.ts",
|
|
20
|
-
"import": "./dist/domain/index.mjs",
|
|
21
|
-
"require": "./dist/domain/index.js"
|
|
22
|
-
},
|
|
23
|
-
"./application": {
|
|
24
|
-
"types": "./dist/application/index.d.ts",
|
|
25
|
-
"import": "./dist/application/index.mjs",
|
|
26
|
-
"require": "./dist/application/index.js"
|
|
27
|
-
},
|
|
28
|
-
"./infrastructure": {
|
|
29
|
-
"types": "./dist/infrastructure/index.d.ts",
|
|
30
|
-
"import": "./dist/infrastructure/index.mjs",
|
|
31
|
-
"require": "./dist/infrastructure/index.js"
|
|
32
|
-
},
|
|
33
|
-
"./presentation": {
|
|
34
|
-
"types": "./dist/presentation/index.d.ts",
|
|
35
|
-
"import": "./dist/presentation/index.mjs",
|
|
36
|
-
"require": "./dist/presentation/index.js"
|
|
37
|
-
}
|
|
12
|
+
".": "./src/index.ts",
|
|
13
|
+
"./auth": "./src/domains/auth/index.ts",
|
|
14
|
+
"./firestore": "./src/domains/firestore/index.ts",
|
|
15
|
+
"./storage": "./src/domains/storage/index.ts",
|
|
16
|
+
"./package.json": "./package.json"
|
|
38
17
|
},
|
|
39
18
|
"files": [
|
|
40
|
-
"dist",
|
|
41
19
|
"src"
|
|
42
20
|
],
|
|
43
21
|
"scripts": {
|
|
44
|
-
"
|
|
45
|
-
"dev": "tsup src/index.ts src/domain/index.ts src/application/index.ts src/infrastructure/index.ts src/presentation/index.ts --format cjs,esm --dts --watch --external react --external firebase",
|
|
46
|
-
"lint": "tsc --noEmit"
|
|
22
|
+
"typecheck": "tsc --noEmit"
|
|
47
23
|
},
|
|
48
24
|
"keywords": [
|
|
49
25
|
"firebase",
|
|
@@ -57,10 +33,8 @@
|
|
|
57
33
|
"typescript",
|
|
58
34
|
"ddd",
|
|
59
35
|
"domain-driven-design",
|
|
60
|
-
"
|
|
61
|
-
"repository-pattern"
|
|
62
|
-
"use-cases",
|
|
63
|
-
"hexagonal-architecture"
|
|
36
|
+
"package-driven",
|
|
37
|
+
"repository-pattern"
|
|
64
38
|
],
|
|
65
39
|
"author": "umituz",
|
|
66
40
|
"license": "MIT",
|
|
@@ -71,7 +45,6 @@
|
|
|
71
45
|
"devDependencies": {
|
|
72
46
|
"@types/react": "^18.2.0",
|
|
73
47
|
"firebase": "^12.11.0",
|
|
74
|
-
"tsup": "^8.0.0",
|
|
75
48
|
"typescript": "^5.0.0"
|
|
76
49
|
}
|
|
77
50
|
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auth Domain Entities
|
|
3
|
+
* @description Core authentication-related entities
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { User as FirebaseUser } from 'firebase/auth'
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Auth User Entity
|
|
10
|
+
* Wrapper around Firebase User with application-specific data
|
|
11
|
+
*/
|
|
12
|
+
export interface AuthUser {
|
|
13
|
+
readonly uid: string
|
|
14
|
+
readonly email: string | null
|
|
15
|
+
readonly emailVerified: boolean
|
|
16
|
+
readonly displayName: string | null
|
|
17
|
+
readonly photoURL: string | null
|
|
18
|
+
readonly phoneNumber: string | null
|
|
19
|
+
readonly isAnonymous: boolean
|
|
20
|
+
readonly tenantId: string | null
|
|
21
|
+
readonly providerId: string
|
|
22
|
+
readonly metadata: {
|
|
23
|
+
readonly creationTime?: number
|
|
24
|
+
readonly lastSignInTime?: number
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Auth State Entity
|
|
30
|
+
* Current authentication state
|
|
31
|
+
*/
|
|
32
|
+
export interface AuthState {
|
|
33
|
+
readonly user: AuthUser | null
|
|
34
|
+
readonly isLoading: boolean
|
|
35
|
+
readonly isInitialized: boolean
|
|
36
|
+
readonly error: Error | null
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Convert Firebase User to Auth User
|
|
41
|
+
*/
|
|
42
|
+
export function toAuthUser(firebaseUser: FirebaseUser | null): AuthUser | null {
|
|
43
|
+
if (!firebaseUser) return null
|
|
44
|
+
|
|
45
|
+
return {
|
|
46
|
+
uid: firebaseUser.uid,
|
|
47
|
+
email: firebaseUser.email,
|
|
48
|
+
emailVerified: firebaseUser.emailVerified,
|
|
49
|
+
displayName: firebaseUser.displayName,
|
|
50
|
+
photoURL: firebaseUser.photoURL,
|
|
51
|
+
phoneNumber: firebaseUser.phoneNumber,
|
|
52
|
+
isAnonymous: firebaseUser.isAnonymous,
|
|
53
|
+
tenantId: firebaseUser.tenantId,
|
|
54
|
+
providerId: firebaseUser.providerId,
|
|
55
|
+
metadata: {
|
|
56
|
+
creationTime: firebaseUser.metadata.creationTime ? new Date(firebaseUser.metadata.creationTime).getTime() : undefined,
|
|
57
|
+
lastSignInTime: firebaseUser.metadata.lastSignInTime ? new Date(firebaseUser.metadata.lastSignInTime).getTime() : undefined,
|
|
58
|
+
},
|
|
59
|
+
}
|
|
60
|
+
}
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auth Service
|
|
3
|
+
* @description Firebase Auth implementation of IAuthService
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
signInWithEmailAndPassword,
|
|
8
|
+
signInWithPopup,
|
|
9
|
+
createUserWithEmailAndPassword,
|
|
10
|
+
signOut as firebaseSignOut,
|
|
11
|
+
sendPasswordResetEmail,
|
|
12
|
+
sendEmailVerification,
|
|
13
|
+
updateProfile as updateAuthProfile,
|
|
14
|
+
updateEmail as updateAuthEmail,
|
|
15
|
+
updatePassword as updateAuthPassword,
|
|
16
|
+
reauthenticateWithCredential,
|
|
17
|
+
EmailAuthProvider,
|
|
18
|
+
UserCredential,
|
|
19
|
+
} from 'firebase/auth'
|
|
20
|
+
import { GoogleAuthProvider } from 'firebase/auth'
|
|
21
|
+
import { getFirebaseAuth } from '../../../infrastructure/firebase/client'
|
|
22
|
+
import type { IAuthService } from '../types'
|
|
23
|
+
import type { AuthUser } from '../entities'
|
|
24
|
+
|
|
25
|
+
class AuthService implements IAuthService {
|
|
26
|
+
private get auth() {
|
|
27
|
+
return getFirebaseAuth()
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Authentication Methods
|
|
31
|
+
|
|
32
|
+
async signIn(email: string, password: string): Promise<UserCredential> {
|
|
33
|
+
try {
|
|
34
|
+
return await signInWithEmailAndPassword(this.auth, email, password)
|
|
35
|
+
} catch (error) {
|
|
36
|
+
throw this.handleAuthError(error)
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
async signUp(email: string, password: string, displayName: string): Promise<UserCredential> {
|
|
41
|
+
try {
|
|
42
|
+
const result = await createUserWithEmailAndPassword(this.auth, email, password)
|
|
43
|
+
|
|
44
|
+
// Update profile
|
|
45
|
+
await updateAuthProfile(result.user, { displayName })
|
|
46
|
+
|
|
47
|
+
// Send email verification
|
|
48
|
+
await sendEmailVerification(result.user)
|
|
49
|
+
|
|
50
|
+
return result
|
|
51
|
+
} catch (error) {
|
|
52
|
+
throw this.handleAuthError(error)
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
async signInWithGoogle(): Promise<UserCredential> {
|
|
57
|
+
try {
|
|
58
|
+
const provider = new GoogleAuthProvider()
|
|
59
|
+
provider.addScope('profile')
|
|
60
|
+
provider.addScope('email')
|
|
61
|
+
|
|
62
|
+
return await signInWithPopup(this.auth, provider)
|
|
63
|
+
} catch (error) {
|
|
64
|
+
throw this.handleAuthError(error)
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
async signOut(): Promise<void> {
|
|
69
|
+
try {
|
|
70
|
+
await firebaseSignOut(this.auth)
|
|
71
|
+
} catch (error) {
|
|
72
|
+
throw new Error('Sign out failed')
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
async sendPasswordReset(email: string): Promise<void> {
|
|
77
|
+
try {
|
|
78
|
+
await sendPasswordResetEmail(this.auth, email)
|
|
79
|
+
} catch (error) {
|
|
80
|
+
throw this.handleAuthError(error)
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
async resendEmailVerification(): Promise<void> {
|
|
85
|
+
try {
|
|
86
|
+
const user = this.auth.currentUser
|
|
87
|
+
if (!user) {
|
|
88
|
+
throw new Error('No user logged in')
|
|
89
|
+
}
|
|
90
|
+
await sendEmailVerification(user)
|
|
91
|
+
} catch (error) {
|
|
92
|
+
throw new Error('Failed to resend verification')
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Profile Management
|
|
97
|
+
|
|
98
|
+
async updateProfile(updates: { displayName?: string; photoURL?: string }): Promise<void> {
|
|
99
|
+
try {
|
|
100
|
+
const user = this.auth.currentUser
|
|
101
|
+
if (!user) {
|
|
102
|
+
throw new Error('No user logged in')
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
await updateAuthProfile(user, updates)
|
|
106
|
+
} catch (error) {
|
|
107
|
+
throw new Error('Profile update failed')
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
async updateEmail(newEmail: string, password: string): Promise<void> {
|
|
112
|
+
try {
|
|
113
|
+
const user = this.auth.currentUser
|
|
114
|
+
if (!user || !user.email) {
|
|
115
|
+
throw new Error('No user logged in')
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const credential = EmailAuthProvider.credential(user.email, password)
|
|
119
|
+
await reauthenticateWithCredential(user, credential)
|
|
120
|
+
await updateAuthEmail(user, newEmail)
|
|
121
|
+
} catch (error) {
|
|
122
|
+
throw new Error('Email update failed')
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
async updatePassword(currentPassword: string, newPassword: string): Promise<void> {
|
|
127
|
+
try {
|
|
128
|
+
const user = this.auth.currentUser
|
|
129
|
+
if (!user || !user.email) {
|
|
130
|
+
throw new Error('No user logged in')
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
const credential = EmailAuthProvider.credential(user.email, currentPassword)
|
|
134
|
+
await reauthenticateWithCredential(user, credential)
|
|
135
|
+
await updateAuthPassword(user, newPassword)
|
|
136
|
+
} catch (error) {
|
|
137
|
+
throw new Error('Password update failed')
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
async deleteAccount(password: string): Promise<void> {
|
|
142
|
+
try {
|
|
143
|
+
const user = this.auth.currentUser
|
|
144
|
+
if (!user || !user.email) {
|
|
145
|
+
throw new Error('No user logged in')
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const credential = EmailAuthProvider.credential(user.email, password)
|
|
149
|
+
await reauthenticateWithCredential(user, credential)
|
|
150
|
+
await user.delete()
|
|
151
|
+
} catch (error) {
|
|
152
|
+
throw new Error('Account deletion failed')
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// State Management
|
|
157
|
+
|
|
158
|
+
getCurrentUser(): AuthUser | null {
|
|
159
|
+
const user = this.auth.currentUser
|
|
160
|
+
if (!user) return null
|
|
161
|
+
|
|
162
|
+
return {
|
|
163
|
+
uid: user.uid,
|
|
164
|
+
email: user.email,
|
|
165
|
+
emailVerified: user.emailVerified,
|
|
166
|
+
displayName: user.displayName,
|
|
167
|
+
photoURL: user.photoURL,
|
|
168
|
+
phoneNumber: user.phoneNumber,
|
|
169
|
+
isAnonymous: user.isAnonymous,
|
|
170
|
+
tenantId: user.tenantId,
|
|
171
|
+
providerId: user.providerId,
|
|
172
|
+
metadata: {
|
|
173
|
+
creationTime: user.metadata.creationTime ? new Date(user.metadata.creationTime).getTime() : undefined,
|
|
174
|
+
lastSignInTime: user.metadata.lastSignInTime ? new Date(user.metadata.lastSignInTime).getTime() : undefined,
|
|
175
|
+
},
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
onAuthStateChanged(
|
|
180
|
+
callback: (user: AuthUser | null) => void,
|
|
181
|
+
onError?: (error: Error) => void
|
|
182
|
+
): () => void {
|
|
183
|
+
return this.auth.onAuthStateChanged(
|
|
184
|
+
(user) => {
|
|
185
|
+
callback(
|
|
186
|
+
user
|
|
187
|
+
? {
|
|
188
|
+
uid: user.uid,
|
|
189
|
+
email: user.email,
|
|
190
|
+
emailVerified: user.emailVerified,
|
|
191
|
+
displayName: user.displayName,
|
|
192
|
+
photoURL: user.photoURL,
|
|
193
|
+
phoneNumber: user.phoneNumber,
|
|
194
|
+
isAnonymous: user.isAnonymous,
|
|
195
|
+
tenantId: user.tenantId,
|
|
196
|
+
providerId: user.providerId,
|
|
197
|
+
metadata: {
|
|
198
|
+
creationTime: user.metadata.creationTime ? new Date(user.metadata.creationTime).getTime() : undefined,
|
|
199
|
+
lastSignInTime: user.metadata.lastSignInTime ? new Date(user.metadata.lastSignInTime).getTime() : undefined,
|
|
200
|
+
},
|
|
201
|
+
}
|
|
202
|
+
: null
|
|
203
|
+
)
|
|
204
|
+
},
|
|
205
|
+
(error) => {
|
|
206
|
+
onError?.(error as Error)
|
|
207
|
+
}
|
|
208
|
+
)
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Handle Firebase Auth errors
|
|
213
|
+
*/
|
|
214
|
+
private handleAuthError(error: unknown): Error {
|
|
215
|
+
if (error instanceof Error && 'code' in error) {
|
|
216
|
+
const code = (error as { code: string }).code
|
|
217
|
+
|
|
218
|
+
switch (code) {
|
|
219
|
+
case 'auth/user-not-found':
|
|
220
|
+
case 'auth/wrong-password':
|
|
221
|
+
case 'auth/invalid-credential':
|
|
222
|
+
return new Error('Invalid credentials')
|
|
223
|
+
case 'auth/email-already-in-use':
|
|
224
|
+
return new Error('Email already in use')
|
|
225
|
+
case 'auth/weak-password':
|
|
226
|
+
return new Error('Password is too weak')
|
|
227
|
+
case 'auth/invalid-email':
|
|
228
|
+
return new Error('Invalid email')
|
|
229
|
+
case 'auth/user-disabled':
|
|
230
|
+
return new Error('Account disabled')
|
|
231
|
+
case 'auth/too-many-requests':
|
|
232
|
+
return new Error('Too many requests')
|
|
233
|
+
case 'auth/popup-closed-by-user':
|
|
234
|
+
return new Error('Sign in cancelled')
|
|
235
|
+
default:
|
|
236
|
+
return new Error(`Auth error: ${code}`)
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
return new Error('Unknown auth error')
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// Export class and singleton instance
|
|
245
|
+
export const authService = new AuthService()
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auth Service Interface
|
|
3
|
+
* @description Abstract interface for authentication operations
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { UserCredential } from 'firebase/auth'
|
|
7
|
+
import type { AuthUser } from '../entities'
|
|
8
|
+
|
|
9
|
+
export interface IAuthService {
|
|
10
|
+
/**
|
|
11
|
+
* Sign in with email and password
|
|
12
|
+
*/
|
|
13
|
+
signIn(email: string, password: string): Promise<UserCredential>
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Sign up with email, password, and display name
|
|
17
|
+
*/
|
|
18
|
+
signUp(email: string, password: string, displayName: string): Promise<UserCredential>
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Sign in with Google OAuth
|
|
22
|
+
*/
|
|
23
|
+
signInWithGoogle(): Promise<UserCredential>
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Sign out current user
|
|
27
|
+
*/
|
|
28
|
+
signOut(): Promise<void>
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Send password reset email
|
|
32
|
+
*/
|
|
33
|
+
sendPasswordReset(email: string): Promise<void>
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Resend email verification
|
|
37
|
+
*/
|
|
38
|
+
resendEmailVerification(): Promise<void>
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Update user profile (displayName, photoURL)
|
|
42
|
+
*/
|
|
43
|
+
updateProfile(updates: { displayName?: string; photoURL?: string }): Promise<void>
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Update user email (requires password)
|
|
47
|
+
*/
|
|
48
|
+
updateEmail(newEmail: string, password: string): Promise<void>
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Update user password (requires current password)
|
|
52
|
+
*/
|
|
53
|
+
updatePassword(currentPassword: string, newPassword: string): Promise<void>
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Delete user account (requires password)
|
|
57
|
+
*/
|
|
58
|
+
deleteAccount(password: string): Promise<void>
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Get current authenticated user
|
|
62
|
+
*/
|
|
63
|
+
getCurrentUser(): AuthUser | null
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Subscribe to auth state changes
|
|
67
|
+
*/
|
|
68
|
+
onAuthStateChanged(
|
|
69
|
+
callback: (user: AuthUser | null) => void,
|
|
70
|
+
onError?: (error: Error) => void
|
|
71
|
+
): () => void
|
|
72
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Firestore Domain Entities
|
|
3
|
+
* @description Core Firestore-related entities
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* User Profile Value Object
|
|
8
|
+
* Immutable user profile data
|
|
9
|
+
*/
|
|
10
|
+
export interface UserProfile {
|
|
11
|
+
readonly id: string
|
|
12
|
+
readonly email: string
|
|
13
|
+
readonly displayName: string
|
|
14
|
+
readonly photoURL?: string
|
|
15
|
+
readonly phoneNumber?: string
|
|
16
|
+
readonly createdAt: number
|
|
17
|
+
readonly updatedAt: number
|
|
18
|
+
readonly lastLoginAt: number
|
|
19
|
+
readonly emailVerified: boolean
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* User Notifications Settings
|
|
24
|
+
*/
|
|
25
|
+
export interface UserNotifications {
|
|
26
|
+
email: boolean
|
|
27
|
+
push: boolean
|
|
28
|
+
marketing: boolean
|
|
29
|
+
security: boolean
|
|
30
|
+
weeklyDigest: boolean
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* User Privacy Settings
|
|
35
|
+
*/
|
|
36
|
+
export interface UserPrivacy {
|
|
37
|
+
profileVisibility: 'public' | 'private'
|
|
38
|
+
showEmail: boolean
|
|
39
|
+
showPhone: boolean
|
|
40
|
+
dataSharing: boolean
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* User Settings Value Object
|
|
45
|
+
*/
|
|
46
|
+
export interface UserSettings {
|
|
47
|
+
theme: 'light' | 'dark' | 'system'
|
|
48
|
+
language: string
|
|
49
|
+
timezone: string
|
|
50
|
+
currency: string
|
|
51
|
+
notifications: UserNotifications
|
|
52
|
+
privacy: UserPrivacy
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* User Subscription Value Object
|
|
57
|
+
*/
|
|
58
|
+
export interface UserSubscription {
|
|
59
|
+
plan: 'free' | 'standard' | 'professional' | 'business'
|
|
60
|
+
status: 'active' | 'inactive' | 'canceled' | 'past_due'
|
|
61
|
+
polarCustomerId?: string
|
|
62
|
+
polarSubscriptionId?: string
|
|
63
|
+
currentPeriodStart?: number
|
|
64
|
+
currentPeriodEnd?: number
|
|
65
|
+
cancelAtPeriodEnd: boolean
|
|
66
|
+
readonly createdAt: number
|
|
67
|
+
readonly updatedAt: number
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* User Aggregate Root
|
|
72
|
+
* Main user document containing all user-related data
|
|
73
|
+
*/
|
|
74
|
+
export interface User {
|
|
75
|
+
readonly profile: UserProfile
|
|
76
|
+
settings: UserSettings
|
|
77
|
+
subscription: UserSubscription
|
|
78
|
+
connectedAccounts?: any[]
|
|
79
|
+
content?: any[]
|
|
80
|
+
analytics?: any
|
|
81
|
+
credits?: any
|
|
82
|
+
}
|