backend-manager 2.5.123 → 2.6.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/CHANGELOG.md +24 -0
- package/package.json +2 -2
- package/src/manager/functions/core/actions/api/admin/get-stats.js +22 -24
- package/src/manager/functions/core/actions/api/user/sign-up.js +4 -2
- package/src/manager/functions/core/events/auth/before-create.js +114 -0
- package/src/manager/functions/core/events/auth/before-signin.js +59 -0
- package/src/manager/functions/core/events/auth/on-create.js +20 -13
- package/src/manager/functions/core/events/auth/on-delete.js +9 -5
- package/src/manager/helpers/user.js +46 -43
- package/src/manager/index.js +23 -4
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# CHANGELOG
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|
6
|
+
|
|
7
|
+
## Changelog Categories
|
|
8
|
+
|
|
9
|
+
- `BREAKING` for breaking changes.
|
|
10
|
+
- `Added` for new features.
|
|
11
|
+
- `Changed` for changes in existing functionality.
|
|
12
|
+
- `Deprecated` for soon-to-be removed features.
|
|
13
|
+
- `Removed` for now removed features.
|
|
14
|
+
- `Fixed` for any bug fixes.
|
|
15
|
+
- `Security` in case of vulnerabilities.
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## [2.6.0] - 2023-09-05
|
|
20
|
+
### Added
|
|
21
|
+
- Identity Platform auth/before-create.js
|
|
22
|
+
- Identity Platform auth/before-signin.js
|
|
23
|
+
- Disable these by passing `options.setupFunctionsIdentity: false`
|
|
24
|
+
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "backend-manager",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.6.0",
|
|
4
4
|
"description": "Quick tools for developing Firebase functions",
|
|
5
5
|
"main": "src/manager/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -66,4 +66,4 @@
|
|
|
66
66
|
"wonderful-log": "^1.0.5",
|
|
67
67
|
"yargs": "^17.7.2"
|
|
68
68
|
}
|
|
69
|
-
}
|
|
69
|
+
}
|
|
@@ -54,7 +54,7 @@ Module.prototype.main = function () {
|
|
|
54
54
|
})
|
|
55
55
|
.catch(function (e) {
|
|
56
56
|
return reject(assistant.errorManager(`Failed to get: ${e}`, {code: 500, sentry: false, send: false, log: false}).error)
|
|
57
|
-
})
|
|
57
|
+
})
|
|
58
58
|
});
|
|
59
59
|
|
|
60
60
|
};
|
|
@@ -79,6 +79,7 @@ Module.prototype.updateStats = function (existingData) {
|
|
|
79
79
|
const stats = self.libraries.admin.firestore().doc(`meta/stats`);
|
|
80
80
|
const gatheringOnline = self.libraries.admin.database().ref(`gatherings/online`);
|
|
81
81
|
const sessionsApp = self.libraries.admin.database().ref(`sessions/app`);
|
|
82
|
+
const sessionsOnline = self.libraries.admin.database().ref(`sessions/online`);
|
|
82
83
|
|
|
83
84
|
let error = null;
|
|
84
85
|
let update = {
|
|
@@ -121,32 +122,29 @@ Module.prototype.updateStats = function (existingData) {
|
|
|
121
122
|
if (error) {
|
|
122
123
|
return reject(error);
|
|
123
124
|
}
|
|
124
|
-
|
|
125
|
+
|
|
126
|
+
const _countUsersOnline = async (app) => {
|
|
127
|
+
await app
|
|
128
|
+
.once('value')
|
|
129
|
+
.then((snap) => {
|
|
130
|
+
const data = snap.val() || {};
|
|
131
|
+
const keys = Object.keys(data);
|
|
132
|
+
const existing = _.get(update, 'users.online', 0)
|
|
133
|
+
_.set(update, 'users.online', existing + keys.length)
|
|
134
|
+
})
|
|
135
|
+
.catch(e => {
|
|
136
|
+
error = new Error(`Failed getting online users: ${e}`);
|
|
137
|
+
})
|
|
138
|
+
}
|
|
139
|
+
|
|
125
140
|
// Count users online (in old gathering)
|
|
126
|
-
await gatheringOnline
|
|
127
|
-
.once('value')
|
|
128
|
-
.then((snap) => {
|
|
129
|
-
const data = snap.val() || {};
|
|
130
|
-
const keys = Object.keys(data);
|
|
131
|
-
const existing = _.get(update, 'users.online', 0)
|
|
132
|
-
_.set(update, 'users.online', existing + keys.length)
|
|
133
|
-
})
|
|
134
|
-
.catch(e => {
|
|
135
|
-
error = new Error(`Failed getting online users: ${e}`);
|
|
136
|
-
})
|
|
141
|
+
await _countUsersOnline(gatheringOnline);
|
|
137
142
|
|
|
138
143
|
// Count users online (in new session)
|
|
139
|
-
await sessionsApp
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
const keys = Object.keys(data);
|
|
144
|
-
const existing = _.get(update, 'users.online', 0)
|
|
145
|
-
_.set(update, 'users.online', existing + keys.length)
|
|
146
|
-
})
|
|
147
|
-
.catch(e => {
|
|
148
|
-
error = new Error(`Failed getting online users: ${e}`);
|
|
149
|
-
})
|
|
144
|
+
await _countUsersOnline(sessionsApp);
|
|
145
|
+
|
|
146
|
+
// Count users online (in new session)
|
|
147
|
+
await _countUsersOnline(sessionsOnine);
|
|
150
148
|
|
|
151
149
|
if (error) {
|
|
152
150
|
return reject(error);
|
|
@@ -111,6 +111,7 @@ Module.prototype.signUp = function (payload) {
|
|
|
111
111
|
// Main geolocation
|
|
112
112
|
ip: assistant.request.ip,
|
|
113
113
|
continent: assistant.request.continent,
|
|
114
|
+
region: assistant.request.region,
|
|
114
115
|
country: assistant.request.country,
|
|
115
116
|
city: assistant.request.city,
|
|
116
117
|
latitude: assistant.request.latitude,
|
|
@@ -120,6 +121,7 @@ Module.prototype.signUp = function (payload) {
|
|
|
120
121
|
userAgent: assistant.request.userAgent,
|
|
121
122
|
language: assistant.request.language,
|
|
122
123
|
platform: assistant.request.platform,
|
|
124
|
+
mobile: assistant.request.mobile,
|
|
123
125
|
},
|
|
124
126
|
},
|
|
125
127
|
affiliate: {
|
|
@@ -127,7 +129,7 @@ Module.prototype.signUp = function (payload) {
|
|
|
127
129
|
},
|
|
128
130
|
metadata: Manager.Metadata().set({tag: 'user:sign-up'}),
|
|
129
131
|
}
|
|
130
|
-
|
|
132
|
+
|
|
131
133
|
assistant.log(`signUp(): user`, user, {environment: 'production'})
|
|
132
134
|
|
|
133
135
|
// Set the user
|
|
@@ -157,7 +159,7 @@ Module.prototype.updateReferral = function (payload) {
|
|
|
157
159
|
payload = payload || {};
|
|
158
160
|
|
|
159
161
|
assistant.log(`updateReferral(): payload`, payload, {environment: 'production'})
|
|
160
|
-
|
|
162
|
+
|
|
161
163
|
self.libraries.admin.firestore().collection('users')
|
|
162
164
|
.where('affiliate.code', '==', payload.affiliateCode)
|
|
163
165
|
.get()
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
const { get, merge } = require('lodash');
|
|
2
|
+
const functions = require('firebase-functions');
|
|
3
|
+
const admin = require('firebase-admin');
|
|
4
|
+
|
|
5
|
+
function Module() {
|
|
6
|
+
const self = this;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
Module.prototype.init = function (Manager, payload) {
|
|
10
|
+
const self = this;
|
|
11
|
+
self.Manager = Manager;
|
|
12
|
+
self.libraries = Manager.libraries;
|
|
13
|
+
self.assistant = Manager.Assistant();
|
|
14
|
+
self.user = payload.user;
|
|
15
|
+
self.context = payload.context;
|
|
16
|
+
|
|
17
|
+
return self;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
Module.prototype.main = function () {
|
|
21
|
+
const self = this;
|
|
22
|
+
const libraries = self.libraries;
|
|
23
|
+
const assistant = self.assistant;
|
|
24
|
+
const user = self.user;
|
|
25
|
+
const context = self.context;
|
|
26
|
+
|
|
27
|
+
return new Promise(async function(resolve, reject) {
|
|
28
|
+
const functions = self.libraries.functions;
|
|
29
|
+
const admin = self.libraries.admin;
|
|
30
|
+
|
|
31
|
+
assistant.log(`Request: ${user.uid}`, user, context, { environment: 'production' });
|
|
32
|
+
|
|
33
|
+
const ipAddress = context.ipAddress;
|
|
34
|
+
const currentTime = Date.now();
|
|
35
|
+
const oneHour = 60 * 60 * 1000; // One hour in milliseconds
|
|
36
|
+
|
|
37
|
+
// Get current rate-limiting data
|
|
38
|
+
const rateLimitingData = await self.Manager.storage({ name: 'rate-limiting' }).get(`ipRateLimits.${ipAddress}`);
|
|
39
|
+
const count = get(rateLimitingData, 'count', 0);
|
|
40
|
+
const lastTime = get(rateLimitingData, 'lastTime', 0);
|
|
41
|
+
|
|
42
|
+
assistant.log(`Rate limiting for ${ipAddress}:`, rateLimitingData, { environment: 'production' });
|
|
43
|
+
|
|
44
|
+
if (currentTime - lastTime < oneHour && count >= 2) {
|
|
45
|
+
assistant.error(`Too many attemps to create an account for ${ipAddress}`, { environment: 'production' });
|
|
46
|
+
|
|
47
|
+
throw new functions.auth.HttpsError('resource-exhausted');
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Update rate-limiting data
|
|
51
|
+
await self.Manager.storage({ name: 'rate-limiting' }).set(`ipRateLimits.${ipAddress}`, { count: count + 1, lastTime: currentTime });
|
|
52
|
+
|
|
53
|
+
const existingAccount = await admin.firestore().doc(`users/${user.uid}`)
|
|
54
|
+
.get()
|
|
55
|
+
.then((doc) => doc.data())
|
|
56
|
+
.catch(e => e);
|
|
57
|
+
|
|
58
|
+
// If user already exists, skip auth-on-create handler
|
|
59
|
+
if (existingAccount instanceof Error) {
|
|
60
|
+
assistant.error(`Failed to get existing account ${user.uid}:`, existingAccount, { environment: 'production' });
|
|
61
|
+
|
|
62
|
+
throw new functions.auth.HttpsError('internal');
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
let account = {
|
|
66
|
+
activity: {
|
|
67
|
+
lastActivity: {
|
|
68
|
+
timestamp: new Date(currentTime).toISOString(),
|
|
69
|
+
timestampUNIX: Math.round(currentTime / 1000),
|
|
70
|
+
},
|
|
71
|
+
geolocation: {
|
|
72
|
+
ip: ipAddress,
|
|
73
|
+
language: context.locale,
|
|
74
|
+
userAgent: context.userAgent,
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
// If it exists, just add the activity data
|
|
80
|
+
if (!get(existingAccount, 'auth.uid', null) || !get(existingAccount, 'auth.email', null)) {
|
|
81
|
+
account = merge(
|
|
82
|
+
self.Manager.User({
|
|
83
|
+
auth: {
|
|
84
|
+
uid: user.uid,
|
|
85
|
+
email: user.email,
|
|
86
|
+
},
|
|
87
|
+
activity: {
|
|
88
|
+
created: {
|
|
89
|
+
timestamp: new Date(currentTime).toISOString(),
|
|
90
|
+
timestampUNIX: Math.round(currentTime / 1000),
|
|
91
|
+
},
|
|
92
|
+
},
|
|
93
|
+
}).properties,
|
|
94
|
+
account,
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// Save IP to Firestore after successful IP check
|
|
99
|
+
const update = await admin.firestore().doc(`users/${user.uid}`)
|
|
100
|
+
.set(account, { merge: true });
|
|
101
|
+
|
|
102
|
+
if (update instanceof Error) {
|
|
103
|
+
assistant.error(`Failed to update user ${user.uid}:`, update, { environment: 'production' });
|
|
104
|
+
|
|
105
|
+
throw new functions.auth.HttpsError('internal');
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
assistant.log(`User created at users/${user.uid}`, account, { environment: 'production' });
|
|
109
|
+
|
|
110
|
+
return resolve(self);
|
|
111
|
+
});
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
module.exports = Module;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
const { get } = require('lodash');
|
|
2
|
+
|
|
3
|
+
function Module() {
|
|
4
|
+
const self = this;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
Module.prototype.init = function (Manager, payload) {
|
|
8
|
+
const self = this;
|
|
9
|
+
self.Manager = Manager;
|
|
10
|
+
self.libraries = Manager.libraries;
|
|
11
|
+
self.assistant = Manager.Assistant();
|
|
12
|
+
self.user = payload.user
|
|
13
|
+
self.context = payload.context
|
|
14
|
+
|
|
15
|
+
return self;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
Module.prototype.main = function () {
|
|
19
|
+
const self = this;
|
|
20
|
+
const libraries = self.libraries;
|
|
21
|
+
const assistant = self.assistant;
|
|
22
|
+
const user = self.user;
|
|
23
|
+
const context = self.context;
|
|
24
|
+
|
|
25
|
+
return new Promise(async function(resolve, reject) {
|
|
26
|
+
|
|
27
|
+
assistant.log(`Request: ${user.uid}`, user, context, {environment: 'production'});
|
|
28
|
+
|
|
29
|
+
const now = new Date();
|
|
30
|
+
|
|
31
|
+
// Save IP to Firestore after successful IP check
|
|
32
|
+
const update = await admin.firestore().doc(`users/${user.uid}`)
|
|
33
|
+
.set({
|
|
34
|
+
activity: {
|
|
35
|
+
lastActivity: {
|
|
36
|
+
timestamp: now.toISOString(),
|
|
37
|
+
timestampUNIX: Math.round(now.getTime() / 1000),
|
|
38
|
+
},
|
|
39
|
+
geolocation: {
|
|
40
|
+
ip: context.ipAddress,
|
|
41
|
+
language: context.locale,
|
|
42
|
+
userAgent: context.userAgent,
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
}, { merge: true });
|
|
46
|
+
|
|
47
|
+
if (update instanceof Error) {
|
|
48
|
+
assistant.error(`Failed to update user ${user.uid}:`, update, { environment: 'production' });
|
|
49
|
+
|
|
50
|
+
throw new functions.auth.HttpsError('internal');
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
assistant.log(`Updated user activity`, {environment: 'production'});
|
|
54
|
+
|
|
55
|
+
return resolve(self);
|
|
56
|
+
});
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
module.exports = Module;
|
|
@@ -10,8 +10,9 @@ Module.prototype.init = function (Manager, payload) {
|
|
|
10
10
|
self.libraries = Manager.libraries;
|
|
11
11
|
self.assistant = Manager.Assistant();
|
|
12
12
|
self.user = payload.user
|
|
13
|
+
self.context = payload.context
|
|
13
14
|
|
|
14
|
-
return self;
|
|
15
|
+
return self;
|
|
15
16
|
};
|
|
16
17
|
|
|
17
18
|
Module.prototype.main = function () {
|
|
@@ -19,8 +20,11 @@ Module.prototype.main = function () {
|
|
|
19
20
|
const libraries = self.libraries;
|
|
20
21
|
const assistant = self.assistant;
|
|
21
22
|
const user = self.user;
|
|
23
|
+
const context = self.context;
|
|
22
24
|
|
|
23
25
|
return new Promise(async function(resolve, reject) {
|
|
26
|
+
assistant.log(`Request: ${user.uid}`, user, context, { environment: 'production' });
|
|
27
|
+
|
|
24
28
|
// Check if exists already
|
|
25
29
|
// It could exist already if user signed up with email and then signed in with Google
|
|
26
30
|
const existingUser = await libraries.admin.firestore().doc(`users/${user.uid}`)
|
|
@@ -29,15 +33,18 @@ Module.prototype.main = function () {
|
|
|
29
33
|
.catch(e => e)
|
|
30
34
|
|
|
31
35
|
// If user already exists, skip auth-on-create handler
|
|
32
|
-
if (
|
|
33
|
-
existingUser
|
|
34
|
-
|
|
36
|
+
if (existingUser instanceof Error) {
|
|
37
|
+
assistant.error(`Failed to get existing user ${user.uid}:`, existingUser, { environment: 'production' });
|
|
38
|
+
|
|
39
|
+
return reject(existingUser);
|
|
40
|
+
} else if (
|
|
41
|
+
get(existingUser, 'auth.uid', null)
|
|
35
42
|
|| get(existingUser, 'auth.email', null)
|
|
36
43
|
) {
|
|
37
|
-
assistant.log(`
|
|
44
|
+
assistant.log(`Skipping handler because user already exists ${user.uid}:`, existingUser, {environment: 'production'});
|
|
38
45
|
|
|
39
|
-
return resolve(self);
|
|
40
|
-
}
|
|
46
|
+
return resolve(self);
|
|
47
|
+
}
|
|
41
48
|
|
|
42
49
|
// Build user object
|
|
43
50
|
const newUser = self.Manager.User({
|
|
@@ -45,7 +52,7 @@ Module.prototype.main = function () {
|
|
|
45
52
|
uid: user.uid,
|
|
46
53
|
email: user.email,
|
|
47
54
|
}
|
|
48
|
-
}).properties;
|
|
55
|
+
}).properties;
|
|
49
56
|
|
|
50
57
|
// Set up analytics
|
|
51
58
|
const analytics = self.Manager.Analytics({
|
|
@@ -64,7 +71,7 @@ Module.prototype.main = function () {
|
|
|
64
71
|
return true
|
|
65
72
|
}
|
|
66
73
|
}).length < 1) {
|
|
67
|
-
return resolve(self);
|
|
74
|
+
return resolve(self);
|
|
68
75
|
}
|
|
69
76
|
|
|
70
77
|
// Add metadata
|
|
@@ -74,7 +81,7 @@ Module.prototype.main = function () {
|
|
|
74
81
|
await libraries.admin.firestore().doc(`users/${newUser.auth.uid}`)
|
|
75
82
|
.set(newUser, {merge: true})
|
|
76
83
|
.catch((e) => {
|
|
77
|
-
assistant.error(`
|
|
84
|
+
assistant.error(`Failed save user record`, e, {environment: 'production'});
|
|
78
85
|
})
|
|
79
86
|
|
|
80
87
|
// Update user count
|
|
@@ -83,12 +90,12 @@ Module.prototype.main = function () {
|
|
|
83
90
|
'users.total': libraries.admin.firestore.FieldValue.increment(1),
|
|
84
91
|
})
|
|
85
92
|
.catch((e) => {
|
|
86
|
-
assistant.error(`
|
|
93
|
+
assistant.error(`Failed to increment user`, e, {environment: 'production'});
|
|
87
94
|
})
|
|
88
95
|
|
|
89
|
-
assistant.log(`
|
|
96
|
+
assistant.log(`User created ${user.uid}:`, newUser, user, context, {environment: 'production'});
|
|
90
97
|
|
|
91
|
-
return resolve(self);
|
|
98
|
+
return resolve(self);
|
|
92
99
|
});
|
|
93
100
|
};
|
|
94
101
|
|
|
@@ -8,8 +8,9 @@ Module.prototype.init = function (Manager, payload) {
|
|
|
8
8
|
self.libraries = Manager.libraries;
|
|
9
9
|
self.assistant = Manager.Assistant();
|
|
10
10
|
self.user = payload.user
|
|
11
|
+
self.context = payload.context
|
|
11
12
|
|
|
12
|
-
return self;
|
|
13
|
+
return self;
|
|
13
14
|
};
|
|
14
15
|
|
|
15
16
|
Module.prototype.main = function () {
|
|
@@ -17,8 +18,11 @@ Module.prototype.main = function () {
|
|
|
17
18
|
const libraries = self.libraries;
|
|
18
19
|
const assistant = self.assistant;
|
|
19
20
|
const user = self.user;
|
|
21
|
+
const context = self.context;
|
|
20
22
|
|
|
21
23
|
return new Promise(async function(resolve, reject) {
|
|
24
|
+
assistant.log(`Request: ${user.uid}`, user, context, { environment: 'production' });
|
|
25
|
+
|
|
22
26
|
// Set up analytics
|
|
23
27
|
const analytics = self.Manager.Analytics({
|
|
24
28
|
assistant: assistant,
|
|
@@ -34,7 +38,7 @@ Module.prototype.main = function () {
|
|
|
34
38
|
await libraries.admin.firestore().doc(`users/${user.uid}`)
|
|
35
39
|
.delete()
|
|
36
40
|
.catch((e) => {
|
|
37
|
-
assistant.error(`
|
|
41
|
+
assistant.error(`Delete user failed`, e, {environment: 'production'});
|
|
38
42
|
})
|
|
39
43
|
|
|
40
44
|
// Update user count
|
|
@@ -43,11 +47,11 @@ Module.prototype.main = function () {
|
|
|
43
47
|
'users.total': libraries.admin.firestore.FieldValue.increment(-1),
|
|
44
48
|
})
|
|
45
49
|
.catch((e) => {
|
|
46
|
-
assistant.error(`
|
|
50
|
+
assistant.error(`Failed to decrement user`, e, {environment: 'production'});
|
|
47
51
|
})
|
|
48
52
|
|
|
49
|
-
assistant.log(`
|
|
50
|
-
|
|
53
|
+
assistant.log(`User deleted ${user.uid}:`, user, context, {environment: 'production'});
|
|
54
|
+
|
|
51
55
|
return resolve(self);
|
|
52
56
|
});
|
|
53
57
|
};
|
|
@@ -13,35 +13,38 @@ function User(Manager, settings, options) {
|
|
|
13
13
|
settings = settings || {};
|
|
14
14
|
options = options || {};
|
|
15
15
|
|
|
16
|
+
options.defaults = typeof options.defaults === 'undefined' ? true : options.defaults;
|
|
17
|
+
options.prune = typeof options.prune === 'undefined' ? false : options.prune;
|
|
18
|
+
|
|
16
19
|
const now = powertools.timestamp(new Date(), {output: 'string'});
|
|
17
20
|
const nowUNIX = powertools.timestamp(now, {output: 'unix'});
|
|
18
21
|
const oldDate = powertools.timestamp(new Date(0), {output: 'string'})
|
|
19
22
|
const oldDateUNIX = powertools.timestamp(oldDate, {output: 'unix'});
|
|
20
23
|
|
|
21
|
-
const
|
|
24
|
+
const defaults = options.defaults;
|
|
22
25
|
|
|
23
26
|
self.properties = {
|
|
24
27
|
auth: {
|
|
25
28
|
uid: _.get(settings, 'auth.uid', null),
|
|
26
29
|
email: _.get(settings, 'auth.email', null),
|
|
27
|
-
temporary: _.get(settings, 'auth.temporary',
|
|
30
|
+
temporary: _.get(settings, 'auth.temporary', defaults ? false : null),
|
|
28
31
|
},
|
|
29
32
|
roles: {
|
|
30
|
-
admin: _.get(settings, 'roles.admin',
|
|
31
|
-
betaTester: _.get(settings, 'roles.betaTester',
|
|
32
|
-
developer: _.get(settings, 'roles.developer',
|
|
33
|
+
admin: _.get(settings, 'roles.admin', defaults ? false : null),
|
|
34
|
+
betaTester: _.get(settings, 'roles.betaTester', defaults ? false : null),
|
|
35
|
+
developer: _.get(settings, 'roles.developer', defaults ? false : null),
|
|
33
36
|
},
|
|
34
37
|
plan: {
|
|
35
|
-
id: _.get(settings, 'plan.id',
|
|
38
|
+
id: _.get(settings, 'plan.id', defaults ? 'basic' : null), // intro | basic | advanced | premium
|
|
36
39
|
expires: {
|
|
37
|
-
timestamp: _.get(settings, 'plan.expires.timestamp',
|
|
38
|
-
timestampUNIX: _.get(settings, 'plan.expires.timestampUNIX',
|
|
40
|
+
timestamp: _.get(settings, 'plan.expires.timestamp', defaults ? oldDate : null),
|
|
41
|
+
timestampUNIX: _.get(settings, 'plan.expires.timestampUNIX', defaults ? oldDateUNIX : null),
|
|
39
42
|
},
|
|
40
43
|
trial: {
|
|
41
|
-
activated: _.get(settings, 'plan.trial.activated',
|
|
44
|
+
activated: _.get(settings, 'plan.trial.activated', defaults ? false : null),
|
|
42
45
|
expires: {
|
|
43
|
-
timestamp: _.get(settings, 'plan.trial.expires.timestamp',
|
|
44
|
-
timestampUNIX: _.get(settings, 'plan.trial.expires.timestampUNIX',
|
|
46
|
+
timestamp: _.get(settings, 'plan.trial.expires.timestamp', defaults ? oldDate : null),
|
|
47
|
+
timestampUNIX: _.get(settings, 'plan.trial.expires.timestampUNIX', defaults ? oldDateUNIX : null),
|
|
45
48
|
},
|
|
46
49
|
},
|
|
47
50
|
limits: {
|
|
@@ -53,71 +56,71 @@ function User(Manager, settings, options) {
|
|
|
53
56
|
resourceId: _.get(settings, 'plan.payment.resourceId', null), // x-xxxxxx
|
|
54
57
|
frequency: _.get(settings, 'plan.payment.frequency', null), // monthly || annually
|
|
55
58
|
startDate: {
|
|
56
|
-
timestamp: _.get(settings, 'plan.payment.startDate.timestamp',
|
|
57
|
-
timestampUNIX: _.get(settings, 'plan.payment.startDate.timestampUNIX',
|
|
59
|
+
timestamp: _.get(settings, 'plan.payment.startDate.timestamp', defaults ? now : null), // x-xxxxxx
|
|
60
|
+
timestampUNIX: _.get(settings, 'plan.payment.startDate.timestampUNIX', defaults ? nowUNIX : null), // x-xxxxxx
|
|
58
61
|
},
|
|
59
|
-
active: _.get(settings, 'plan.payment.active',
|
|
62
|
+
active: _.get(settings, 'plan.payment.active', defaults ? false : null), // true | false
|
|
60
63
|
updatedBy: {
|
|
61
64
|
event: {
|
|
62
65
|
name: _.get(settings, 'plan.payment.updatedBy.event.name', null), // x-xxxxxx
|
|
63
66
|
id: _.get(settings, 'plan.payment.updatedBy.event.id', null), // x-xxxxxx
|
|
64
67
|
},
|
|
65
68
|
date: {
|
|
66
|
-
timestamp: _.get(settings, 'plan.payment.updatedBy.date.timestamp',
|
|
67
|
-
timestampUNIX: _.get(settings, 'plan.payment.updatedBy.date.timestampUNIX',
|
|
69
|
+
timestamp: _.get(settings, 'plan.payment.updatedBy.date.timestamp', defaults ? now : null), // x-xxxxxx
|
|
70
|
+
timestampUNIX: _.get(settings, 'plan.payment.updatedBy.date.timestampUNIX', defaults ? nowUNIX : null), // x-xxxxxx
|
|
68
71
|
},
|
|
69
72
|
},
|
|
70
73
|
}
|
|
71
74
|
},
|
|
72
75
|
affiliate: {
|
|
73
|
-
code: _.get(settings, 'affiliate.code',
|
|
76
|
+
code: _.get(settings, 'affiliate.code', defaults ? shortid.generate() : null),
|
|
74
77
|
referrals: [],
|
|
75
78
|
referrer: _.get(settings, 'affiliate.referrer', null),
|
|
76
79
|
},
|
|
77
80
|
activity: {
|
|
78
81
|
lastActivity: {
|
|
79
|
-
timestamp: _.get(settings, 'activity.lastActivity.timestamp',
|
|
80
|
-
timestampUNIX: _.get(settings, 'activity.lastActivity.timestampUNIX',
|
|
82
|
+
timestamp: _.get(settings, 'activity.lastActivity.timestamp', defaults ? now : null),
|
|
83
|
+
timestampUNIX: _.get(settings, 'activity.lastActivity.timestampUNIX', defaults ? nowUNIX : null),
|
|
81
84
|
},
|
|
82
85
|
created: {
|
|
83
|
-
timestamp: _.get(settings, 'activity.created.timestamp',
|
|
84
|
-
timestampUNIX: _.get(settings, 'activity.created.timestampUNIX',
|
|
86
|
+
timestamp: _.get(settings, 'activity.created.timestamp', defaults ? now : null),
|
|
87
|
+
timestampUNIX: _.get(settings, 'activity.created.timestampUNIX', defaults ? nowUNIX : null),
|
|
85
88
|
},
|
|
86
89
|
geolocation: {
|
|
87
|
-
ip: _.get(settings, 'activity.geolocation.ip',
|
|
88
|
-
continent: _.get(settings, 'activity.geolocation.continent',
|
|
89
|
-
country: _.get(settings, 'activity.geolocation.country',
|
|
90
|
-
city: _.get(settings, 'activity.geolocation.city',
|
|
91
|
-
latitude: _.get(settings, 'activity.geolocation.latitude',
|
|
92
|
-
longitude: _.get(settings, 'activity.geolocation.longitude',
|
|
93
|
-
userAgent: _.get(settings, 'activity.geolocation.userAgent',
|
|
94
|
-
language: _.get(settings, 'activity.geolocation.language',
|
|
95
|
-
platform: _.get(settings, 'activity.geolocation.platform',
|
|
90
|
+
ip: _.get(settings, 'activity.geolocation.ip', defaults ? '' : null),
|
|
91
|
+
continent: _.get(settings, 'activity.geolocation.continent', defaults ? '' : null),
|
|
92
|
+
country: _.get(settings, 'activity.geolocation.country', defaults ? '' : null),
|
|
93
|
+
city: _.get(settings, 'activity.geolocation.city', defaults ? '' : null),
|
|
94
|
+
latitude: _.get(settings, 'activity.geolocation.latitude', defaults ? 0 : null),
|
|
95
|
+
longitude: _.get(settings, 'activity.geolocation.longitude', defaults ? 0 : null),
|
|
96
|
+
userAgent: _.get(settings, 'activity.geolocation.userAgent', defaults ? '' : null),
|
|
97
|
+
language: _.get(settings, 'activity.geolocation.language', defaults ? '' : null),
|
|
98
|
+
platform: _.get(settings, 'activity.geolocation.platform', defaults ? '' : null),
|
|
96
99
|
},
|
|
97
100
|
},
|
|
98
101
|
api: {
|
|
99
|
-
clientId: _.get(settings, 'api.clientId',
|
|
100
|
-
privateKey: _.get(settings, 'api.privateKey',
|
|
102
|
+
clientId: _.get(settings, 'api.clientId', defaults ? `${uuid4()}` : null),
|
|
103
|
+
privateKey: _.get(settings, 'api.privateKey', defaults ? `${uidgen.generateSync()}` : null),
|
|
101
104
|
},
|
|
102
105
|
personal: {
|
|
103
106
|
birthday: {
|
|
104
|
-
timestamp: _.get(settings, 'personal.birthday.timestamp',
|
|
105
|
-
timestampUNIX: _.get(settings, 'personal.birthday.timestampUNIX',
|
|
107
|
+
timestamp: _.get(settings, 'personal.birthday.timestamp', defaults ? oldDate : null),
|
|
108
|
+
timestampUNIX: _.get(settings, 'personal.birthday.timestampUNIX', defaults ? oldDateUNIX : null),
|
|
106
109
|
},
|
|
107
|
-
gender: _.get(settings, 'personal.gender',
|
|
110
|
+
gender: _.get(settings, 'personal.gender', defaults ? '' : null),
|
|
108
111
|
location: {
|
|
109
|
-
city: _.get(settings, 'personal.location.city',
|
|
110
|
-
country: _.get(settings, 'personal.location.country',
|
|
112
|
+
city: _.get(settings, 'personal.location.city', defaults ? '' : null),
|
|
113
|
+
country: _.get(settings, 'personal.location.country', defaults ? '' : null),
|
|
111
114
|
},
|
|
112
115
|
name: {
|
|
113
|
-
first: _.get(settings, 'personal.name.first',
|
|
114
|
-
last: _.get(settings, 'personal.name.last',
|
|
116
|
+
first: _.get(settings, 'personal.name.first', defaults ? '' : null),
|
|
117
|
+
last: _.get(settings, 'personal.name.last', defaults ? '' : null),
|
|
115
118
|
},
|
|
116
119
|
telephone: {
|
|
117
|
-
countryCode: _.get(settings, 'personal.telephone.countryCode',
|
|
118
|
-
national: _.get(settings, 'personal.telephone.national',
|
|
119
|
-
},
|
|
120
|
-
},
|
|
120
|
+
countryCode: _.get(settings, 'personal.telephone.countryCode', defaults ? 0 : null),
|
|
121
|
+
national: _.get(settings, 'personal.telephone.national', defaults ? 0 : null),
|
|
122
|
+
},
|
|
123
|
+
},
|
|
121
124
|
}
|
|
122
125
|
|
|
123
126
|
if (options.prune) {
|
package/src/manager/index.js
CHANGED
|
@@ -38,6 +38,7 @@ Manager.prototype.init = function (exporter, options) {
|
|
|
38
38
|
options.log = typeof options.log === 'undefined' ? false : options.log;
|
|
39
39
|
options.setupFunctions = typeof options.setupFunctions === 'undefined' ? true : options.setupFunctions;
|
|
40
40
|
options.setupFunctionsLegacy = typeof options.setupFunctionsLegacy === 'undefined' ? true : options.setupFunctionsLegacy;
|
|
41
|
+
options.setupFunctionsIdentity = typeof options.setupFunctionsIdentity === 'undefined' ? true : options.setupFunctionsIdentity;
|
|
41
42
|
options.initializeLocalStorage = typeof options.initializeLocalStorage === 'undefined' ? false : options.initializeLocalStorage;
|
|
42
43
|
options.resourceZone = typeof options.resourceZone === 'undefined' ? 'us-central1' : options.resourceZone;
|
|
43
44
|
options.sentry = typeof options.sentry === 'undefined' ? true : options.sentry;
|
|
@@ -371,20 +372,38 @@ Manager.prototype.init = function (exporter, options) {
|
|
|
371
372
|
}
|
|
372
373
|
|
|
373
374
|
// Events
|
|
375
|
+
if (options.setupFunctionsIdentity) {
|
|
376
|
+
exporter.bm_authBeforeCreate =
|
|
377
|
+
self.libraries.functions
|
|
378
|
+
.runWith({memory: '256MB', timeoutSeconds: 60})
|
|
379
|
+
.auth.user()
|
|
380
|
+
.beforeCreate(async (user, context) => {
|
|
381
|
+
return self._process((new (require(`${core}/events/auth/before-create.js`))()).init(self, { user: user, context: context}))
|
|
382
|
+
});
|
|
383
|
+
|
|
384
|
+
exporter.bm_authBeforeSignIn =
|
|
385
|
+
self.libraries.functions
|
|
386
|
+
.runWith({memory: '256MB', timeoutSeconds: 60})
|
|
387
|
+
.auth.user()
|
|
388
|
+
.beforeSignIn(async (user, context) => {
|
|
389
|
+
return self._process((new (require(`${core}/events/auth/before-signin.js`))()).init(self, { user: user, context: context}))
|
|
390
|
+
});
|
|
391
|
+
}
|
|
392
|
+
|
|
374
393
|
exporter.bm_authOnCreate =
|
|
375
394
|
self.libraries.functions
|
|
376
395
|
.runWith({memory: '256MB', timeoutSeconds: 60})
|
|
377
396
|
.auth.user()
|
|
378
|
-
.onCreate(async (user) => {
|
|
379
|
-
return self._process((new (require(`${core}/events/auth/on-create.js`))()).init(self, { user: user, }))
|
|
397
|
+
.onCreate(async (user, context) => {
|
|
398
|
+
return self._process((new (require(`${core}/events/auth/on-create.js`))()).init(self, { user: user, context: context}))
|
|
380
399
|
});
|
|
381
400
|
|
|
382
401
|
exporter.bm_authOnDelete =
|
|
383
402
|
self.libraries.functions
|
|
384
403
|
.runWith({memory: '256MB', timeoutSeconds: 60})
|
|
385
404
|
.auth.user()
|
|
386
|
-
.onDelete(async (user) => {
|
|
387
|
-
return self._process((new (require(`${core}/events/auth/on-delete.js`))()).init(self, { user: user, }))
|
|
405
|
+
.onDelete(async (user, context) => {
|
|
406
|
+
return self._process((new (require(`${core}/events/auth/on-delete.js`))()).init(self, { user: user, context: context}))
|
|
388
407
|
});
|
|
389
408
|
|
|
390
409
|
exporter.bm_subOnWrite =
|