Skip to content

Commit f4a93a1

Browse files
authored
Merge branch 'develop' into view-logs
2 parents 41f0195 + b644572 commit f4a93a1

File tree

86 files changed

+1392
-405
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

86 files changed

+1392
-405
lines changed

.storybook/mocks/meteor.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,9 @@ export const check = () => {};
6464

6565
export const FlowRouter = {
6666
route: () => {},
67+
group: () => ({
68+
route: () => {},
69+
}),
6770
};
6871

6972
export const BlazeLayout = {};

app/api/server/lib/rooms.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ export async function findAdminRooms({ uid, filter, types = [], pagination: { of
1818
unmuted: 1,
1919
ro: 1,
2020
default: 1,
21+
favorite: 1,
2122
featured: 1,
2223
topic: 1,
2324
msgs: 1,

app/api/server/v1/channels.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -758,7 +758,7 @@ API.v1.addRoute('channels.setDefault', { authRequired: true }, {
758758
}
759759

760760
Meteor.runAsUser(this.userId, () => {
761-
Meteor.call('saveRoomSettings', findResult._id, 'default', this.bodyParams.default.toString());
761+
Meteor.call('saveRoomSettings', findResult._id, 'default', ['true', '1'].includes(this.bodyParams.default.toString().toLowerCase()));
762762
});
763763

764764
return API.v1.success({

app/channel-settings/server/methods/saveRoomSettings.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import { saveRoomTokenpass } from '../functions/saveRoomTokens';
1717
import { saveStreamingOptions } from '../functions/saveStreamingOptions';
1818
import { RoomSettingsEnum, roomTypes } from '../../../utils';
1919

20-
const fields = ['featured', 'roomName', 'roomTopic', 'roomAnnouncement', 'roomCustomFields', 'roomDescription', 'roomType', 'readOnly', 'reactWhenReadOnly', 'systemMessages', 'default', 'joinCode', 'tokenpass', 'streamingOptions', 'retentionEnabled', 'retentionMaxAge', 'retentionExcludePinned', 'retentionFilesOnly', 'retentionOverrideGlobal', 'encrypted'];
20+
const fields = ['featured', 'roomName', 'roomTopic', 'roomAnnouncement', 'roomCustomFields', 'roomDescription', 'roomType', 'readOnly', 'reactWhenReadOnly', 'systemMessages', 'default', 'joinCode', 'tokenpass', 'streamingOptions', 'retentionEnabled', 'retentionMaxAge', 'retentionExcludePinned', 'retentionFilesOnly', 'retentionOverrideGlobal', 'encrypted', 'favorite'];
2121
Meteor.methods({
2222
saveRoomSettings(rid, settings, value) {
2323
const userId = Meteor.userId();
@@ -221,6 +221,9 @@ Meteor.methods({
221221
case 'encrypted':
222222
Rooms.saveEncryptedById(rid, value);
223223
break;
224+
case 'favorite':
225+
Rooms.saveFavoriteById(rid, value.favorite, value.defaultValue);
226+
break;
224227
}
225228
});
226229

app/custom-oauth/server/custom_oauth_server.js

Lines changed: 49 additions & 126 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { HTTP } from 'meteor/http';
66
import { ServiceConfiguration } from 'meteor/service-configuration';
77
import _ from 'underscore';
88

9+
import { normalizers, fromTemplate, renameInvalidProperties } from './transform_helpers';
910
import { mapRolesFromSSO, updateRolesFromSSO } from './oauth_helpers';
1011
import { Logger } from '../../logger';
1112
import { Users } from '../../models';
@@ -17,107 +18,6 @@ const logger = new Logger('CustomOAuth');
1718
const Services = {};
1819
const BeforeUpdateOrCreateUserFromExternalService = [];
1920

20-
const normalizers = {
21-
// Set 'id' to '_id' for any sources that provide it
22-
_id(identity) {
23-
if (identity._id && !identity.id) {
24-
identity.id = identity._id;
25-
}
26-
},
27-
28-
// Fix for Reddit
29-
redit(identity) {
30-
if (identity.result) {
31-
return identity.result;
32-
}
33-
},
34-
35-
// Fix WordPress-like identities having 'ID' instead of 'id'
36-
wordpress(identity) {
37-
if (identity.ID && !identity.id) {
38-
identity.id = identity.ID;
39-
}
40-
},
41-
42-
// Fix Auth0-like identities having 'user_id' instead of 'id'
43-
user_id(identity) {
44-
if (identity.user_id && !identity.id) {
45-
identity.id = identity.user_id;
46-
}
47-
},
48-
49-
characterid(identity) {
50-
if (identity.CharacterID && !identity.id) {
51-
identity.id = identity.CharacterID;
52-
}
53-
},
54-
55-
// Fix Dataporten having 'user.userid' instead of 'id'
56-
dataporten(identity) {
57-
if (identity.user && identity.user.userid && !identity.id) {
58-
if (identity.user.userid_sec && identity.user.userid_sec[0]) {
59-
identity.id = identity.user.userid_sec[0];
60-
} else {
61-
identity.id = identity.user.userid;
62-
}
63-
identity.email = identity.user.email;
64-
}
65-
},
66-
67-
// Fix for Xenforo [BD]API plugin for 'user.user_id; instead of 'id'
68-
xenforo(identity) {
69-
if (identity.user && identity.user.user_id && !identity.id) {
70-
identity.id = identity.user.user_id;
71-
identity.email = identity.user.user_email;
72-
}
73-
},
74-
75-
// Fix general 'phid' instead of 'id' from phabricator
76-
phabricator(identity) {
77-
if (identity.phid && !identity.id) {
78-
identity.id = identity.phid;
79-
}
80-
},
81-
82-
// Fix Keycloak-like identities having 'sub' instead of 'id'
83-
kaycloak(identity) {
84-
if (identity.sub && !identity.id) {
85-
identity.id = identity.sub;
86-
}
87-
},
88-
89-
// Fix OpenShift identities where id is in 'metadata' object
90-
openshift(identity) {
91-
if (!identity.id && identity.metadata && identity.metadata.uid) {
92-
identity.id = identity.metadata.uid;
93-
identity.name = identity.fullName;
94-
}
95-
},
96-
97-
// Fix general 'userid' instead of 'id' from provider
98-
userid(identity) {
99-
if (identity.userid && !identity.id) {
100-
identity.id = identity.userid;
101-
}
102-
},
103-
104-
// Fix Nextcloud provider
105-
nextcloud(identity) {
106-
if (!identity.id && identity.ocs && identity.ocs.data && identity.ocs.data.id) {
107-
identity.id = identity.ocs.data.id;
108-
identity.name = identity.ocs.data.displayname;
109-
identity.email = identity.ocs.data.email;
110-
}
111-
},
112-
113-
// Fix when authenticating from a meteor app with 'emails' field
114-
meteor(identity) {
115-
if (!identity.email && (identity.emails && Array.isArray(identity.emails) && identity.emails.length >= 1)) {
116-
identity.email = identity.emails[0].address ? identity.emails[0].address : undefined;
117-
}
118-
},
119-
};
120-
12121
export class CustomOAuth {
12222
constructor(name, options) {
12323
logger.debug('Init CustomOAuth', name, options);
@@ -174,6 +74,7 @@ export class CustomOAuth {
17474
this.tokenSentVia = options.tokenSentVia;
17575
this.identityTokenSentVia = options.identityTokenSentVia;
17676
this.usernameField = (options.usernameField || '').trim();
77+
this.emailField = (options.emailField || '').trim();
17778
this.nameField = (options.nameField || '').trim();
17879
this.avatarField = (options.avatarField || '').trim();
17980
this.mergeUsers = options.mergeUsers;
@@ -334,6 +235,10 @@ export class CustomOAuth {
334235
identity.username = this.getUsername(identity);
335236
}
336237

238+
if (this.emailField) {
239+
identity.email = this.getEmail(identity);
240+
}
241+
337242
if (this.avatarField) {
338243
identity.avatarUrl = this.getAvatarUrl(identity);
339244
}
@@ -344,50 +249,64 @@ export class CustomOAuth {
344249
identity.name = this.getName(identity);
345250
}
346251

347-
return identity;
252+
return renameInvalidProperties(identity);
348253
}
349254

350255
retrieveCredential(credentialToken, credentialSecret) {
351256
return OAuth.retrieveCredential(credentialToken, credentialSecret);
352257
}
353258

354259
getUsername(data) {
355-
let username = '';
260+
try {
261+
const value = fromTemplate(this.usernameField, data);
262+
263+
if (!value) {
264+
throw new Meteor.Error('field_not_found', `Username field "${ this.usernameField }" not found in data`, data);
265+
}
266+
return value;
267+
} catch (error) {
268+
throw new Error('CustomOAuth: Failed to extract username', error.message);
269+
}
270+
}
356271

357-
username = this.usernameField.split('.').reduce(function(prev, curr) {
358-
return prev ? prev[curr] : undefined;
359-
}, data);
272+
getEmail(data) {
273+
try {
274+
const value = fromTemplate(this.emailField, data);
360275

361-
if (!username) {
362-
throw new Meteor.Error('field_not_found', `Username field "${ this.usernameField }" not found in data`, data);
276+
if (!value) {
277+
throw new Meteor.Error('field_not_found', `Email field "${ this.emailField }" not found in data`, data);
278+
}
279+
return value;
280+
} catch (error) {
281+
throw new Error('CustomOAuth: Failed to extract email', error.message);
363282
}
364-
return username;
365283
}
366284

367285
getCustomName(data) {
368-
let customName = '';
286+
try {
287+
const value = fromTemplate(this.nameField, data);
369288

370-
customName = this.nameField.split('.').reduce(function(prev, curr) {
371-
return prev ? prev[curr] : undefined;
372-
}, data);
289+
if (!value) {
290+
return this.getName(data);
291+
}
373292

374-
if (!customName) {
375-
return this.getName(data);
293+
return value;
294+
} catch (error) {
295+
throw new Error('CustomOAuth: Failed to extract custom name', error.message);
376296
}
377-
378-
return customName;
379297
}
380298

381299
getAvatarUrl(data) {
382-
const avatarUrl = this.avatarField.split('.').reduce(function(prev, curr) {
383-
return prev ? prev[curr] : undefined;
384-
}, data);
300+
try {
301+
const value = fromTemplate(this.avatarField, data);
385302

386-
if (!avatarUrl) {
387-
logger.debug(`Avatar field "${ this.avatarField }" not found in data`, data);
303+
if (!value) {
304+
logger.debug(`Avatar field "${ this.avatarField }" not found in data`, data);
305+
}
306+
return value;
307+
} catch (error) {
308+
throw new Error('CustomOAuth: Failed to extract avatar url', error.message);
388309
}
389-
390-
return avatarUrl;
391310
}
392311

393312
getName(identity) {
@@ -438,11 +357,15 @@ export class CustomOAuth {
438357
}
439358

440359
if (this.usernameField) {
441-
user.username = this.getUsername(user.services[this.name]);
360+
user.username = user.services[this.name].username;
361+
}
362+
363+
if (this.emailField) {
364+
user.email = user.services[this.name].email;
442365
}
443366

444367
if (this.nameField) {
445-
user.name = this.getCustomName(user.services[this.name]);
368+
user.name = user.services[this.name].name;
446369
}
447370

448371
if (this.mergeRoles) {

0 commit comments

Comments
 (0)