omnibiofex 2.8.4 → 4.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/bin/obx +30 -158
- package/package.json +13 -28
- package/src/auth.js +181 -320
- package/src/commands/account.js +34 -87
- package/src/commands/data.js +40 -114
- package/src/commands/debug.js +28 -25
- package/src/commands/earnings.js +31 -86
- package/src/commands/mission.js +194 -98
- package/src/commands/morning.js +39 -107
- package/src/commands/open.js +26 -36
- package/src/commands/publish.js +80 -125
- package/src/commands/research.js +148 -281
- package/src/commands/timeline.js +15 -54
- package/src/firebase.js +4 -112
- package/src/user.js +94 -0
- package/src/utils/display.js +27 -856
- package/src/api.js +0 -72
- package/src/config.js +0 -16
package/src/firebase.js
CHANGED
|
@@ -1,18 +1,17 @@
|
|
|
1
|
+
// Firebase client SDK - kept for backward compatibility
|
|
2
|
+
// Most commands now use backend REST endpoints instead
|
|
1
3
|
const { initializeApp, getApps } = require('firebase/app');
|
|
2
|
-
const { getAuth } = require('firebase/auth');
|
|
3
4
|
const { getFirestore } = require('firebase/firestore');
|
|
4
|
-
const Conf = require('conf');
|
|
5
5
|
|
|
6
6
|
const firebaseConfig = {
|
|
7
7
|
apiKey: "AIzaSyDlgXId4pLlYqm-MDuhfz3dLH24KBRHkw8",
|
|
8
|
-
authDomain: "
|
|
8
|
+
authDomain: "x.omnibiofex.cloud",
|
|
9
9
|
projectId: "omnibiofex-x",
|
|
10
10
|
storageBucket: "omnibiofex-x.firebasestorage.app",
|
|
11
11
|
messagingSenderId: "292246591666",
|
|
12
12
|
appId: "1:292246591666:web:a182851585e4b0f79511ab"
|
|
13
13
|
};
|
|
14
14
|
|
|
15
|
-
// Initialize Firebase only once
|
|
16
15
|
let app;
|
|
17
16
|
if (getApps().length === 0) {
|
|
18
17
|
app = initializeApp(firebaseConfig);
|
|
@@ -20,113 +19,6 @@ if (getApps().length === 0) {
|
|
|
20
19
|
app = getApps()[0];
|
|
21
20
|
}
|
|
22
21
|
|
|
23
|
-
const auth = getAuth(app);
|
|
24
22
|
const db = getFirestore(app);
|
|
25
23
|
|
|
26
|
-
|
|
27
|
-
const tokenStore = new Conf({
|
|
28
|
-
projectName: 'omnibiofex',
|
|
29
|
-
schema: {
|
|
30
|
-
token: { type: 'string' },
|
|
31
|
-
refreshToken: { type: 'string' },
|
|
32
|
-
expiresAt: { type: 'number' }
|
|
33
|
-
}
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* Decode base64url to string (handles JWT format)
|
|
38
|
-
* @param {string} str - Base64url encoded string
|
|
39
|
-
* @returns {string} - Decoded string
|
|
40
|
-
*/
|
|
41
|
-
function base64UrlDecode(str) {
|
|
42
|
-
// Replace URL-safe characters with standard base64
|
|
43
|
-
let base64 = str.replace(/-/g, '+').replace(/_/g, '/');
|
|
44
|
-
// Add padding if needed
|
|
45
|
-
while (base64.length % 4) {
|
|
46
|
-
base64 += '=';
|
|
47
|
-
}
|
|
48
|
-
return Buffer.from(base64, 'base64').toString('utf8');
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* Decode JWT token to extract user info
|
|
53
|
-
* @returns {Object|null} - { uid, email, exp } or null if no token
|
|
54
|
-
*/
|
|
55
|
-
function decodeToken() {
|
|
56
|
-
const token = tokenStore.get('token');
|
|
57
|
-
if (!token) return null;
|
|
58
|
-
|
|
59
|
-
try {
|
|
60
|
-
// JWT format: header.payload.signature
|
|
61
|
-
const parts = token.split('.');
|
|
62
|
-
if (parts.length !== 3) {
|
|
63
|
-
console.error('Invalid JWT format: expected 3 parts, got', parts.length);
|
|
64
|
-
return null;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
// Decode payload (base64url)
|
|
68
|
-
const payload = parts[1];
|
|
69
|
-
const decoded = base64UrlDecode(payload);
|
|
70
|
-
const data = JSON.parse(decoded);
|
|
71
|
-
|
|
72
|
-
// Firebase tokens use 'user_id' or 'sub' for UID
|
|
73
|
-
const uid = data.user_id || data.sub;
|
|
74
|
-
|
|
75
|
-
if (!uid) {
|
|
76
|
-
console.error('No user_id or sub found in token payload');
|
|
77
|
-
console.error('Token payload keys:', Object.keys(data));
|
|
78
|
-
return null;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
return {
|
|
82
|
-
uid: uid,
|
|
83
|
-
email: data.email,
|
|
84
|
-
exp: data.exp
|
|
85
|
-
};
|
|
86
|
-
} catch (error) {
|
|
87
|
-
console.error('Token decode error:', error.message);
|
|
88
|
-
return null;
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* Get current user UID from stored token
|
|
94
|
-
* @returns {string|null} - User UID or null
|
|
95
|
-
*/
|
|
96
|
-
function getCurrentUserUid() {
|
|
97
|
-
const decoded = decodeToken();
|
|
98
|
-
return decoded ? decoded.uid : null;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
/**
|
|
102
|
-
* Get current user email from stored token
|
|
103
|
-
* @returns {string|null} - User email or null
|
|
104
|
-
*/
|
|
105
|
-
function getCurrentUserEmail() {
|
|
106
|
-
const decoded = decodeToken();
|
|
107
|
-
return decoded ? decoded.email : null;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
* Check if token is valid (not expired)
|
|
112
|
-
* @returns {boolean}
|
|
113
|
-
*/
|
|
114
|
-
function isTokenValid() {
|
|
115
|
-
const decoded = decodeToken();
|
|
116
|
-
if (!decoded || !decoded.exp) return false;
|
|
117
|
-
|
|
118
|
-
// JWT exp is in seconds, Date.now() is in milliseconds
|
|
119
|
-
const now = Math.floor(Date.now() / 1000);
|
|
120
|
-
return decoded.exp > now;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
module.exports = {
|
|
124
|
-
app,
|
|
125
|
-
auth,
|
|
126
|
-
db,
|
|
127
|
-
tokenStore,
|
|
128
|
-
decodeToken,
|
|
129
|
-
getCurrentUserUid,
|
|
130
|
-
getCurrentUserEmail,
|
|
131
|
-
isTokenValid
|
|
132
|
-
};
|
|
24
|
+
module.exports = { app, db };
|
package/src/user.js
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
const Conf = require('conf');
|
|
2
|
+
|
|
3
|
+
const config = new Conf({
|
|
4
|
+
projectName: 'omnibiofex',
|
|
5
|
+
schema: {
|
|
6
|
+
token: { type: 'string' },
|
|
7
|
+
refreshToken: { type: 'string' },
|
|
8
|
+
expiresAt: { type: 'number' },
|
|
9
|
+
userEmail: { type: 'string' },
|
|
10
|
+
userUid: { type: 'string' },
|
|
11
|
+
userName: { type: 'string' }
|
|
12
|
+
}
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
function base64UrlDecode(str) {
|
|
16
|
+
let base64 = str.replace(/-/g, '+').replace(/_/g, '/');
|
|
17
|
+
while (base64.length % 4) base64 += '=';
|
|
18
|
+
return Buffer.from(base64, 'base64').toString('utf8');
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function decodeToken() {
|
|
22
|
+
const token = config.get('token');
|
|
23
|
+
if (!token) return null;
|
|
24
|
+
try {
|
|
25
|
+
const parts = token.split('.');
|
|
26
|
+
if (parts.length !== 3) return null;
|
|
27
|
+
const data = JSON.parse(base64UrlDecode(parts[1]));
|
|
28
|
+
return {
|
|
29
|
+
uid: data.user_id || data.sub,
|
|
30
|
+
email: data.email,
|
|
31
|
+
exp: data.exp,
|
|
32
|
+
name: data.name
|
|
33
|
+
};
|
|
34
|
+
} catch (error) {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function getCurrentUserUid() {
|
|
40
|
+
return config.get('userUid') || decodeToken()?.uid || null;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function getCurrentUserEmail() {
|
|
44
|
+
return config.get('userEmail') || decodeToken()?.email || null;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function getCurrentUserName() {
|
|
48
|
+
return config.get('userName') || decodeToken()?.name || null;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function getToken() {
|
|
52
|
+
return config.get('token');
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function getRefreshToken() {
|
|
56
|
+
return config.get('refreshToken');
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function setToken(token, refreshToken, expiresAt, userInfo = {}) {
|
|
60
|
+
config.set('token', token);
|
|
61
|
+
if (refreshToken) config.set('refreshToken', refreshToken);
|
|
62
|
+
if (expiresAt) config.set('expiresAt', expiresAt);
|
|
63
|
+
if (userInfo.email) config.set('userEmail', userInfo.email);
|
|
64
|
+
if (userInfo.uid) config.set('userUid', userInfo.uid);
|
|
65
|
+
if (userInfo.name) config.set('userName', userInfo.name);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function clearTokens() {
|
|
69
|
+
config.delete('token');
|
|
70
|
+
config.delete('refreshToken');
|
|
71
|
+
config.delete('expiresAt');
|
|
72
|
+
config.delete('userEmail');
|
|
73
|
+
config.delete('userUid');
|
|
74
|
+
config.delete('userName');
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function isTokenExpired() {
|
|
78
|
+
const expiresAt = config.get('expiresAt');
|
|
79
|
+
if (!expiresAt) return true;
|
|
80
|
+
return expiresAt < Math.floor(Date.now() / 1000);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
module.exports = {
|
|
84
|
+
config,
|
|
85
|
+
decodeToken,
|
|
86
|
+
getCurrentUserUid,
|
|
87
|
+
getCurrentUserEmail,
|
|
88
|
+
getCurrentUserName,
|
|
89
|
+
getToken,
|
|
90
|
+
getRefreshToken,
|
|
91
|
+
setToken,
|
|
92
|
+
clearTokens,
|
|
93
|
+
isTokenExpired
|
|
94
|
+
};
|