@libreapps/auth 3.0.1
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/.turbo/turbo-build.log +4 -0
- package/CHANGELOG.md +20 -0
- package/LICENSE.md +21 -0
- package/README.md +61 -0
- package/components/auth-widget.tsx +110 -0
- package/components/email-password-form.tsx +96 -0
- package/components/index.ts +4 -0
- package/components/login-panel.tsx +207 -0
- package/components/signup-panel.tsx +213 -0
- package/dist/components/auth-widget.d.ts +13 -0
- package/dist/components/auth-widget.js +33 -0
- package/dist/components/auth-widget.js.map +1 -0
- package/dist/components/email-password-form.d.ts +8 -0
- package/dist/components/email-password-form.js +25 -0
- package/dist/components/email-password-form.js.map +1 -0
- package/dist/components/index.d.ts +4 -0
- package/dist/components/index.js +5 -0
- package/dist/components/index.js.map +1 -0
- package/dist/components/login-panel.d.ts +13 -0
- package/dist/components/login-panel.js +104 -0
- package/dist/components/login-panel.js.map +1 -0
- package/dist/components/signup-panel.d.ts +13 -0
- package/dist/components/signup-panel.js +104 -0
- package/dist/components/signup-panel.js.map +1 -0
- package/dist/icons/ethereum.d.ts +4 -0
- package/dist/icons/ethereum.js +6 -0
- package/dist/icons/ethereum.js.map +1 -0
- package/dist/icons/facebook.d.ts +4 -0
- package/dist/icons/facebook.js +6 -0
- package/dist/icons/facebook.js.map +1 -0
- package/dist/icons/github.d.ts +4 -0
- package/dist/icons/github.js +6 -0
- package/dist/icons/github.js.map +1 -0
- package/dist/icons/google.d.ts +4 -0
- package/dist/icons/google.js +6 -0
- package/dist/icons/google.js.map +1 -0
- package/dist/icons/index.d.ts +6 -0
- package/dist/icons/index.js +7 -0
- package/dist/icons/index.js.map +1 -0
- package/dist/index.d.ts +24 -0
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -0
- package/dist/server/firebase-support.d.ts +8 -0
- package/dist/server/firebase-support.js +151 -0
- package/dist/server/firebase-support.js.map +1 -0
- package/dist/server/index.d.ts +4 -0
- package/dist/server/index.js +7 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/rest-api-handlers.d.ts +4 -0
- package/dist/server/rest-api-handlers.js +23 -0
- package/dist/server/rest-api-handlers.js.map +1 -0
- package/dist/server/stub-server.d.ts +14 -0
- package/dist/server/stub-server.js +23 -0
- package/dist/server/stub-server.js.map +1 -0
- package/dist/service/auth-service.d.ts +29 -0
- package/dist/service/auth-service.js +2 -0
- package/dist/service/auth-service.js.map +1 -0
- package/dist/service/context.d.ts +9 -0
- package/dist/service/context.js +16 -0
- package/dist/service/context.js.map +1 -0
- package/dist/service/get-singleton.d.ts +4 -0
- package/dist/service/get-singleton.js +24 -0
- package/dist/service/get-singleton.js.map +1 -0
- package/dist/service/impl/firebase-support.d.ts +34 -0
- package/dist/service/impl/firebase-support.js +190 -0
- package/dist/service/impl/firebase-support.js.map +1 -0
- package/dist/service/impl/index.d.ts +32 -0
- package/dist/service/impl/index.js +179 -0
- package/dist/service/impl/index.js.map +1 -0
- package/dist/service/impl/stub-auth-service.d.ts +42 -0
- package/dist/service/impl/stub-auth-service.js +97 -0
- package/dist/service/impl/stub-auth-service.js.map +1 -0
- package/dist/service/impl/wallet-support.d.ts +8 -0
- package/dist/service/impl/wallet-support.js +82 -0
- package/dist/service/impl/wallet-support.js.map +1 -0
- package/dist/service/index.d.ts +4 -0
- package/dist/service/index.js +4 -0
- package/dist/service/index.js.map +1 -0
- package/dist/service/provider-registry.d.ts +37 -0
- package/dist/service/provider-registry.js +58 -0
- package/dist/service/provider-registry.js.map +1 -0
- package/dist/types/api-response.d.ts +8 -0
- package/dist/types/api-response.js +2 -0
- package/dist/types/api-response.js.map +1 -0
- package/dist/types/auth-service-conf.d.ts +5 -0
- package/dist/types/auth-service-conf.js +2 -0
- package/dist/types/auth-service-conf.js.map +1 -0
- package/dist/types/index.d.ts +4 -0
- package/dist/types/index.js +2 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/libreapps-user-info-value.d.ts +6 -0
- package/dist/types/libreapps-user-info-value.js +2 -0
- package/dist/types/libreapps-user-info-value.js.map +1 -0
- package/dist/types/libreapps-user-info.d.ts +6 -0
- package/dist/types/libreapps-user-info.js +2 -0
- package/dist/types/libreapps-user-info.js.map +1 -0
- package/dist/util/analytics.d.ts +9 -0
- package/dist/util/analytics.js +10 -0
- package/dist/util/analytics.js.map +1 -0
- package/icons/ethereum.tsx +18 -0
- package/icons/facebook.tsx +11 -0
- package/icons/github.tsx +14 -0
- package/icons/google.tsx +13 -0
- package/icons/index.ts +16 -0
- package/index.ts +51 -0
- package/libreapps-ui.d.ts +23 -0
- package/package.json +57 -0
- package/server/firebase-support.ts +176 -0
- package/server/index.ts +14 -0
- package/server/rest-api-handlers.ts +33 -0
- package/server/stub-server.ts +28 -0
- package/service/auth-service.ts +21 -0
- package/service/context.tsx +46 -0
- package/service/get-singleton.ts +37 -0
- package/service/impl/firebase-support.ts +241 -0
- package/service/impl/index.ts +231 -0
- package/service/impl/stub-auth-service.ts +131 -0
- package/service/impl/wallet-support.ts +100 -0
- package/service/index.ts +11 -0
- package/service/provider-registry.ts +71 -0
- package/tsconfig.json +15 -0
- package/types/api-response.ts +5 -0
- package/types/auth-service-conf.ts +9 -0
- package/types/index.ts +6 -0
- package/types/libreapps-user-info-value.ts +9 -0
- package/types/libreapps-user-info.ts +9 -0
- package/util/analytics.ts +21 -0
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stub Authentication Service
|
|
3
|
+
*
|
|
4
|
+
* This implementation is used when no auth provider is configured.
|
|
5
|
+
* All auth operations return unsuccessful results gracefully.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { makeAutoObservable, makeObservable, computed } from 'mobx'
|
|
9
|
+
|
|
10
|
+
import type AuthService from '../auth-service'
|
|
11
|
+
import type { AuthServiceConf, LibreAppsUserInfo, LibreAppsUserInfoValue } from '../../types'
|
|
12
|
+
|
|
13
|
+
class LibreAppsUserInfoStore implements LibreAppsUserInfo {
|
|
14
|
+
|
|
15
|
+
constructor() {
|
|
16
|
+
makeAutoObservable(this)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
_email: string = ''
|
|
20
|
+
_displayName: string | null = null
|
|
21
|
+
_walletAddress: string | null = null
|
|
22
|
+
|
|
23
|
+
get email(): string { return this._email}
|
|
24
|
+
get displayName(): string | null { return this._displayName}
|
|
25
|
+
get walletAddress(): string | null { return this._walletAddress}
|
|
26
|
+
|
|
27
|
+
clear():void {
|
|
28
|
+
this._email = ''
|
|
29
|
+
this._displayName = null
|
|
30
|
+
this._walletAddress = null
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
set(v: LibreAppsUserInfoValue):void {
|
|
34
|
+
this._email = v.email
|
|
35
|
+
this._displayName = v.displayName
|
|
36
|
+
this._walletAddress = v.walletAddress
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
get isValid(): boolean {
|
|
40
|
+
return (this._email.length > 0)
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Stub auth service that does nothing but returns graceful failures.
|
|
46
|
+
* Used when no auth provider is configured.
|
|
47
|
+
*/
|
|
48
|
+
export class StubAuthService implements AuthService {
|
|
49
|
+
|
|
50
|
+
private _hzUser = new LibreAppsUserInfoStore()
|
|
51
|
+
|
|
52
|
+
constructor(conf: AuthServiceConf, user: LibreAppsUserInfoValue | null) {
|
|
53
|
+
makeObservable(this, {
|
|
54
|
+
loggedIn: computed,
|
|
55
|
+
user: computed
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
if (user) {
|
|
59
|
+
this._hzUser.set(user)
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
get user(): LibreAppsUserInfo | null {
|
|
64
|
+
return this._hzUser.isValid ? this._hzUser : null
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
get loggedIn(): boolean {
|
|
68
|
+
return this._hzUser.isValid
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
signupEmailAndPassword = async (
|
|
72
|
+
_email: string,
|
|
73
|
+
_password: string
|
|
74
|
+
): Promise<{success: boolean, userInfo: LibreAppsUserInfo | null, message?: string}> => {
|
|
75
|
+
console.warn('Auth provider not configured. Install @libreapps/auth-firebase or another auth provider.')
|
|
76
|
+
return {
|
|
77
|
+
success: false,
|
|
78
|
+
userInfo: null,
|
|
79
|
+
message: 'Auth provider not configured'
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
loginEmailAndPassword = async (
|
|
84
|
+
_email: string,
|
|
85
|
+
_password: string
|
|
86
|
+
): Promise<{success: boolean, userInfo: LibreAppsUserInfo | null, message?: string}> => {
|
|
87
|
+
console.warn('Auth provider not configured. Install @libreapps/auth-firebase or another auth provider.')
|
|
88
|
+
return {
|
|
89
|
+
success: false,
|
|
90
|
+
userInfo: null,
|
|
91
|
+
message: 'Auth provider not configured'
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
loginWithProvider = async (
|
|
96
|
+
_provider: 'google' | 'facebook' | 'github'
|
|
97
|
+
): Promise<{success: boolean, userInfo: LibreAppsUserInfo | null}> => {
|
|
98
|
+
console.warn('Auth provider not configured. Install @libreapps/auth-firebase or another auth provider.')
|
|
99
|
+
return {
|
|
100
|
+
success: false,
|
|
101
|
+
userInfo: null
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
loginWithCustomToken = async (
|
|
106
|
+
_token: string
|
|
107
|
+
): Promise<{success: boolean, userInfo: LibreAppsUserInfo | null}> => {
|
|
108
|
+
console.warn('Auth provider not configured. Install @libreapps/auth-firebase or another auth provider.')
|
|
109
|
+
return {
|
|
110
|
+
success: false,
|
|
111
|
+
userInfo: null
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
associateWallet = async (): Promise<void> => {
|
|
116
|
+
console.warn('Auth provider not configured. Install @libreapps/auth-firebase or another auth provider.')
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
logout = async (): Promise<{ success: boolean }> => {
|
|
120
|
+
this._hzUser.clear()
|
|
121
|
+
return { success: true }
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
setServerSideUser = (user: LibreAppsUserInfoValue | null) => {
|
|
125
|
+
if (user) {
|
|
126
|
+
this._hzUser.set(user)
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export default StubAuthService
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
|
|
2
|
+
import { collection, doc, getDoc, setDoc } from 'firebase/firestore'
|
|
3
|
+
|
|
4
|
+
import { auth, db } from './firebase-support'
|
|
5
|
+
|
|
6
|
+
const isObject = (obj: any): obj is Record<any, any> => typeof obj === 'object' && obj !== null
|
|
7
|
+
const isGlobalThisEthereum = (obj: any): obj is { ethereum: { request: <R = any>(payload: Record<any, any>) => Promise<R> } } => isObject(obj) && isObject(obj.ethereum) && typeof obj.ethereum.request === 'function'
|
|
8
|
+
const getEthereum = (obj: any) => isGlobalThisEthereum(obj) ? obj.ethereum : null
|
|
9
|
+
|
|
10
|
+
const ethereum = getEthereum(globalThis)
|
|
11
|
+
|
|
12
|
+
let signMessage = (opts: { siteName: string, address: string }) => `${opts.siteName} wants you to sign in with your Ethereum account:\n${opts.address}`
|
|
13
|
+
|
|
14
|
+
const USER_INFO_COLLECTION = 'HZ_USER_INFO'
|
|
15
|
+
|
|
16
|
+
async function connectWalletAddress(siteName?: string) {
|
|
17
|
+
if (!ethereum) {
|
|
18
|
+
throw new Error('No ethereum provider found')
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
if (!auth) {
|
|
22
|
+
throw new Error('Firebase auth not configured')
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const [account] = await ethereum.request<string[]>({ method: 'eth_requestAccounts' })
|
|
26
|
+
|
|
27
|
+
if (!account) {
|
|
28
|
+
throw new Error('No account found')
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const signed = await ethereum.request<string>({
|
|
32
|
+
method: 'personal_sign',
|
|
33
|
+
params: [
|
|
34
|
+
signMessage({
|
|
35
|
+
siteName: siteName ?? auth.app.options.projectId ?? globalThis.location.hostname,
|
|
36
|
+
address: account,
|
|
37
|
+
}),
|
|
38
|
+
account,
|
|
39
|
+
auth.app.options.appId,
|
|
40
|
+
],
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
if (!signed) {
|
|
44
|
+
throw new Error('Not signed')
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return {account, signed}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export async function associateWalletAddressWithAccount(userEmail: string, siteName?: string) {
|
|
51
|
+
const {account} = await connectWalletAddress(siteName)
|
|
52
|
+
|
|
53
|
+
if (!db) {
|
|
54
|
+
return { result: null, error: new Error('Firebase Firestore not configured') }
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
let result = null
|
|
58
|
+
let error = null
|
|
59
|
+
const accountsRef = collection(db, USER_INFO_COLLECTION)
|
|
60
|
+
|
|
61
|
+
try {
|
|
62
|
+
try {
|
|
63
|
+
await setDoc(doc(accountsRef, userEmail), { walletAddress: account })
|
|
64
|
+
result = account
|
|
65
|
+
} catch (e) {
|
|
66
|
+
console.error(e)
|
|
67
|
+
error = e
|
|
68
|
+
}
|
|
69
|
+
} catch (e) {
|
|
70
|
+
console.error(e)
|
|
71
|
+
error = e
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return { result, error }
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export async function getAssociatedWalletAddress(userEmail: string) : Promise<{error: any, result?: string}> {
|
|
78
|
+
if (!db) {
|
|
79
|
+
return { error: new Error('Firebase Firestore not configured'), result: undefined }
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
let result = undefined
|
|
83
|
+
let error = null
|
|
84
|
+
try {
|
|
85
|
+
try {
|
|
86
|
+
const docRef = await getDoc(doc(db, USER_INFO_COLLECTION, userEmail))
|
|
87
|
+
result = docRef.data() ? docRef.data()!.walletAddress as string : undefined
|
|
88
|
+
}
|
|
89
|
+
catch (e) {
|
|
90
|
+
console.error(e)
|
|
91
|
+
error = e
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
catch (e) {
|
|
95
|
+
console.error(e)
|
|
96
|
+
error = e
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return { result, error }
|
|
100
|
+
}
|
package/service/index.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export type { default as AuthService, AuthProvider } from './auth-service'
|
|
2
|
+
export { useAuth, AuthServiceProvider } from './context'
|
|
3
|
+
export {
|
|
4
|
+
registerAuthProvider,
|
|
5
|
+
setActiveProvider,
|
|
6
|
+
getActiveProvider,
|
|
7
|
+
hasAuthProvider,
|
|
8
|
+
getRegisteredProviders,
|
|
9
|
+
type AuthServiceFactory
|
|
10
|
+
} from './provider-registry'
|
|
11
|
+
export { StubAuthService } from './impl/stub-auth-service'
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auth Provider Registry
|
|
3
|
+
*
|
|
4
|
+
* Allows registration of pluggable auth providers.
|
|
5
|
+
* Firebase support is available via @libreapps/auth-firebase (optional).
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type AuthService from './auth-service'
|
|
9
|
+
import type { AuthServiceConf, LibreAppsUserInfoValue } from '../types'
|
|
10
|
+
|
|
11
|
+
export type AuthServiceFactory = new (
|
|
12
|
+
conf: AuthServiceConf,
|
|
13
|
+
user: LibreAppsUserInfoValue | null
|
|
14
|
+
) => AuthService
|
|
15
|
+
|
|
16
|
+
// Registry of available auth providers
|
|
17
|
+
const providers = new Map<string, AuthServiceFactory>()
|
|
18
|
+
|
|
19
|
+
// Current active provider
|
|
20
|
+
let activeProvider: string | null = null
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Register an auth provider
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```ts
|
|
27
|
+
* import { FirebaseAuthService } from '@libreapps/auth-firebase'
|
|
28
|
+
* import { registerAuthProvider } from '@libreapps/auth'
|
|
29
|
+
*
|
|
30
|
+
* registerAuthProvider('firebase', FirebaseAuthService)
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
export function registerAuthProvider(name: string, factory: AuthServiceFactory): void {
|
|
34
|
+
providers.set(name, factory)
|
|
35
|
+
// Auto-activate if this is the first provider
|
|
36
|
+
if (!activeProvider) {
|
|
37
|
+
activeProvider = name
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Set the active auth provider by name
|
|
43
|
+
*/
|
|
44
|
+
export function setActiveProvider(name: string): void {
|
|
45
|
+
if (!providers.has(name)) {
|
|
46
|
+
throw new Error(`Auth provider '${name}' is not registered`)
|
|
47
|
+
}
|
|
48
|
+
activeProvider = name
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Get the active auth provider factory
|
|
53
|
+
*/
|
|
54
|
+
export function getActiveProvider(): AuthServiceFactory | null {
|
|
55
|
+
if (!activeProvider) return null
|
|
56
|
+
return providers.get(activeProvider) ?? null
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Check if any auth provider is registered
|
|
61
|
+
*/
|
|
62
|
+
export function hasAuthProvider(): boolean {
|
|
63
|
+
return providers.size > 0
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Get list of registered provider names
|
|
68
|
+
*/
|
|
69
|
+
export function getRegisteredProviders(): string[] {
|
|
70
|
+
return Array.from(providers.keys())
|
|
71
|
+
}
|
package/tsconfig.json
ADDED
package/types/index.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export type { default as LibreAppsUserInfo } from './libreapps-user-info'
|
|
2
|
+
export type { default as APIResponse } from './api-response'
|
|
3
|
+
export type { default as AuthServiceConf } from './auth-service-conf'
|
|
4
|
+
export type { default as LibreAppsUserInfoValue } from './libreapps-user-info-value'
|
|
5
|
+
|
|
6
|
+
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
declare global {
|
|
2
|
+
interface Window {
|
|
3
|
+
fbq: Function;
|
|
4
|
+
gtag: Function;
|
|
5
|
+
}
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
// https://developers.facebook.com/docs/meta-pixel/reference
|
|
9
|
+
const sendFBEvent = (name: string, options = {}) => {
|
|
10
|
+
window.fbq('track', name, options)
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// https://developers.google.com/analytics/devguides/collection/ga4/ecommerce?client_type=gtag
|
|
14
|
+
const sendGAEvent = (name: string, options = {}) => {
|
|
15
|
+
window.gtag('event', name, options)
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export {
|
|
19
|
+
sendFBEvent,
|
|
20
|
+
sendGAEvent,
|
|
21
|
+
}
|