mirror of
https://github.com/wekan/wekan.git
synced 2025-12-17 07:50:12 +01:00
Add support for external email verification
Add support for external email verification against OIDC login script. This will check local file for presence of email and log the user in if it is or deny them if it isn't.
This commit is contained in:
parent
575e3750f1
commit
30273709ae
1 changed files with 205 additions and 294 deletions
|
|
@ -1,349 +1,260 @@
|
|||
import {addGroupsWithAttributes, addEmail, changeFullname, changeUsername} from './loginHandler';
|
||||
import { addGroupsWithAttributes, addEmail, changeFullname, changeUsername } from './loginHandler';
|
||||
const fs = Npm.require('fs'); // For file handling
|
||||
|
||||
Oidc = {};
|
||||
httpCa = false;
|
||||
|
||||
// Load CA certificate if specified in the environment variable
|
||||
if (process.env.OAUTH2_CA_CERT !== undefined) {
|
||||
try {
|
||||
const fs = Npm.require('fs');
|
||||
if (fs.existsSync(process.env.OAUTH2_CA_CERT)) {
|
||||
httpCa = fs.readFileSync(process.env.OAUTH2_CA_CERT);
|
||||
httpCa = fs.readFileSync(process.env.OAUTH2_CA_CERT);
|
||||
}
|
||||
} catch(e) {
|
||||
console.log('WARNING: failed loading: ' + process.env.OAUTH2_CA_CERT);
|
||||
console.log(e);
|
||||
} catch (e) {
|
||||
console.log('WARNING: failed loading: ' + process.env.OAUTH2_CA_CERT);
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
|
||||
var profile = {};
|
||||
var serviceData = {};
|
||||
var userinfo = {};
|
||||
|
||||
// Function to read the allowed emails from a local file specified in the environment variable
|
||||
var getAllowedEmailsFromFile = function() {
|
||||
var allowedEmails = [];
|
||||
const filePath = process.env.OAUTH2_ALLOWEDEMAILS_FILEPATH; // Get the file path from environment variable
|
||||
|
||||
if (!filePath) {
|
||||
throw new Error("OAUTH2_ALLOWEDEMAILS_FILEPATH environment variable is not set.");
|
||||
}
|
||||
|
||||
try {
|
||||
// Read the allowed emails file
|
||||
const data = fs.readFileSync(filePath, 'utf-8');
|
||||
allowedEmails = data.split('\n').map(email => email.trim());
|
||||
} catch (error) {
|
||||
console.error("Error reading allowed emails file:", error);
|
||||
}
|
||||
return allowedEmails;
|
||||
};
|
||||
|
||||
// OAuth service registration
|
||||
OAuth.registerService('oidc', 2, null, function (query) {
|
||||
var debug = process.env.DEBUG === 'true';
|
||||
var debug = process.env.DEBUG === 'true';
|
||||
|
||||
var token = getToken(query);
|
||||
if (debug) console.log('XXX: register token:', token);
|
||||
var token = getToken(query);
|
||||
if (debug) console.log('XXX: register token:', token);
|
||||
|
||||
var accessToken = token.access_token || token.id_token;
|
||||
var expiresAt = (+new Date) + (1000 * parseInt(token.expires_in, 10));
|
||||
var accessToken = token.access_token || token.id_token;
|
||||
var expiresAt = (+new Date) + (1000 * parseInt(token.expires_in, 10));
|
||||
|
||||
var claimsInAccessToken = (process.env.OAUTH2_ADFS_ENABLED === 'true' ||
|
||||
process.env.OAUTH2_ADFS_ENABLED === true ||
|
||||
process.env.OAUTH2_B2C_ENABLED === 'true' ||
|
||||
process.env.OAUTH2_B2C_ENABLED === true) || false;
|
||||
var claimsInAccessToken = (process.env.OAUTH2_ADFS_ENABLED === 'true' ||
|
||||
process.env.OAUTH2_ADFS_ENABLED === true ||
|
||||
process.env.OAUTH2_B2C_ENABLED === 'true' ||
|
||||
process.env.OAUTH2_B2C_ENABLED === true) || false;
|
||||
|
||||
if(claimsInAccessToken)
|
||||
{
|
||||
// hack when using custom claims in the accessToken. On premise ADFS. And Azure AD B2C.
|
||||
userinfo = getTokenContent(accessToken);
|
||||
}
|
||||
else
|
||||
{
|
||||
// normal behaviour, getting the claims from UserInfo endpoint.
|
||||
userinfo = getUserInfo(accessToken);
|
||||
}
|
||||
|
||||
if (userinfo.ocs) userinfo = userinfo.ocs.data; // Nextcloud hack
|
||||
if (userinfo.metadata) userinfo = userinfo.metadata // Openshift hack
|
||||
if (debug) console.log('XXX: userinfo:', userinfo);
|
||||
|
||||
serviceData.id = userinfo[process.env.OAUTH2_ID_MAP]; // || userinfo["id"];
|
||||
serviceData.username = userinfo[process.env.OAUTH2_USERNAME_MAP]; // || userinfo["uid"];
|
||||
serviceData.fullname = userinfo[process.env.OAUTH2_FULLNAME_MAP]; // || userinfo["displayName"];
|
||||
serviceData.accessToken = accessToken;
|
||||
serviceData.expiresAt = expiresAt;
|
||||
|
||||
|
||||
// If on Oracle OIM email is empty or null, get info from username
|
||||
if (process.env.ORACLE_OIM_ENABLED === 'true' || process.env.ORACLE_OIM_ENABLED === true) {
|
||||
if (userinfo[process.env.OAUTH2_EMAIL_MAP]) {
|
||||
serviceData.email = userinfo[process.env.OAUTH2_EMAIL_MAP];
|
||||
if (claimsInAccessToken) {
|
||||
userinfo = getTokenContent(accessToken);
|
||||
} else {
|
||||
serviceData.email = userinfo[process.env.OAUTH2_USERNAME_MAP];
|
||||
userinfo = getUserInfo(accessToken);
|
||||
}
|
||||
}
|
||||
|
||||
if (process.env.ORACLE_OIM_ENABLED !== 'true' && process.env.ORACLE_OIM_ENABLED !== true) {
|
||||
serviceData.email = userinfo[process.env.OAUTH2_EMAIL_MAP]; // || userinfo["email"];
|
||||
}
|
||||
if (userinfo.ocs) userinfo = userinfo.ocs.data;
|
||||
if (userinfo.metadata) userinfo = userinfo.metadata;
|
||||
if (debug) console.log('XXX: userinfo:', userinfo);
|
||||
|
||||
if (process.env.OAUTH2_B2C_ENABLED === 'true' || process.env.OAUTH2_B2C_ENABLED === true) {
|
||||
serviceData.email = userinfo["emails"][0];
|
||||
}
|
||||
serviceData.id = userinfo[process.env.OAUTH2_ID_MAP];
|
||||
serviceData.username = userinfo[process.env.OAUTH2_USERNAME_MAP];
|
||||
serviceData.fullname = userinfo[process.env.OAUTH2_FULLNAME_MAP];
|
||||
serviceData.accessToken = accessToken;
|
||||
serviceData.expiresAt = expiresAt;
|
||||
|
||||
if (accessToken) {
|
||||
var tokenContent = getTokenContent(accessToken);
|
||||
var fields = _.pick(tokenContent, getConfiguration().idTokenWhitelistFields);
|
||||
_.extend(serviceData, fields);
|
||||
}
|
||||
// Oracle OIM and B2C checks remain the same
|
||||
if (process.env.ORACLE_OIM_ENABLED === 'true' || process.env.ORACLE_OIM_ENABLED === true) {
|
||||
if (userinfo[process.env.OAUTH2_EMAIL_MAP]) {
|
||||
serviceData.email = userinfo[process.env.OAUTH2_EMAIL_MAP];
|
||||
} else {
|
||||
serviceData.email = userinfo[process.env.OAUTH2_USERNAME_MAP];
|
||||
}
|
||||
}
|
||||
|
||||
if (token.refresh_token)
|
||||
serviceData.refreshToken = token.refresh_token;
|
||||
if (debug) console.log('XXX: serviceData:', serviceData);
|
||||
if (process.env.ORACLE_OIM_ENABLED !== 'true' && process.env.ORACLE_OIM_ENABLED !== true) {
|
||||
serviceData.email = userinfo[process.env.OAUTH2_EMAIL_MAP];
|
||||
}
|
||||
|
||||
profile.name = userinfo[process.env.OAUTH2_FULLNAME_MAP]; // || userinfo["displayName"];
|
||||
profile.email = userinfo[process.env.OAUTH2_EMAIL_MAP]; // || userinfo["email"];
|
||||
if (process.env.OAUTH2_B2C_ENABLED === 'true' || process.env.OAUTH2_B2C_ENABLED === true) {
|
||||
serviceData.email = userinfo["emails"][0];
|
||||
}
|
||||
|
||||
if (process.env.OAUTH2_B2C_ENABLED === 'true' || process.env.OAUTH2_B2C_ENABLED === true) {
|
||||
profile.email = userinfo["emails"][0];
|
||||
}
|
||||
if (accessToken) {
|
||||
var tokenContent = getTokenContent(accessToken);
|
||||
var fields = _.pick(tokenContent, getConfiguration().idTokenWhitelistFields);
|
||||
_.extend(serviceData, fields);
|
||||
}
|
||||
|
||||
if (debug) console.log('XXX: profile:', profile);
|
||||
if (token.refresh_token)
|
||||
serviceData.refreshToken = token.refresh_token;
|
||||
if (debug) console.log('XXX: serviceData:', serviceData);
|
||||
|
||||
profile.name = userinfo[process.env.OAUTH2_FULLNAME_MAP];
|
||||
profile.email = userinfo[process.env.OAUTH2_EMAIL_MAP];
|
||||
|
||||
//temporarily store data from oidc in user.services.oidc.groups to update groups
|
||||
serviceData.groups = (userinfo["groups"] && userinfo["wekanGroups"]) ? userinfo["wekanGroups"] : userinfo["groups"];
|
||||
// groups arriving as array of strings indicate there is no scope set in oidc privider
|
||||
// to assign teams and keep admin privileges
|
||||
// data needs to be treated differently.
|
||||
// use case: in oidc provider no scope is set, hence no group attributes.
|
||||
// therefore: keep admin privileges for wekan as before
|
||||
if(Array.isArray(serviceData.groups) && serviceData.groups.length && typeof serviceData.groups[0] === "string" )
|
||||
{
|
||||
user = Meteor.users.findOne({'_id': serviceData.id});
|
||||
if (process.env.OAUTH2_B2C_ENABLED === 'true' || process.env.OAUTH2_B2C_ENABLED === true) {
|
||||
profile.email = userinfo["emails"][0];
|
||||
}
|
||||
|
||||
serviceData.groups.forEach(function(groupName, i)
|
||||
{
|
||||
if(user?.isAdmin && i == 0)
|
||||
{
|
||||
// keep information of user.isAdmin since in loginHandler the user will // be updated regarding group admin privileges provided via oidc
|
||||
serviceData.groups[i] = {"isAdmin": true};
|
||||
serviceData.groups[i]["displayName"]= groupName;
|
||||
}
|
||||
else
|
||||
{
|
||||
serviceData.groups[i] = {"displayName": groupName};
|
||||
}
|
||||
});
|
||||
}
|
||||
if (debug) console.log('XXX: profile:', profile);
|
||||
|
||||
// Fix OIDC login loop for integer user ID. Thanks to danielkaiser.
|
||||
// https://github.com/wekan/wekan/issues/4795
|
||||
Meteor.call('groupRoutineOnLogin',serviceData, ""+serviceData.id);
|
||||
Meteor.call('boardRoutineOnLogin',serviceData, ""+serviceData.id);
|
||||
// New code: Check if the user's email is in the allowed emails list (only if oauth2-checkemails is true)
|
||||
if (process.env.OAUTH2_CHECKEMAILS === 'true') {
|
||||
const allowedEmails = getAllowedEmailsFromFile();
|
||||
if (!allowedEmails.includes(profile.email)) {
|
||||
throw new Error("Email not allowed: " + profile.email);
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
serviceData: serviceData,
|
||||
options: { profile: profile }
|
||||
};
|
||||
// Temporarily store data from oidc in user.services.oidc.groups to update groups
|
||||
serviceData.groups = (userinfo["groups"] && userinfo["wekanGroups"]) ? userinfo["wekanGroups"] : userinfo["groups"];
|
||||
|
||||
if (Array.isArray(serviceData.groups) && serviceData.groups.length && typeof serviceData.groups[0] === "string") {
|
||||
user = Meteor.users.findOne({'_id': serviceData.id});
|
||||
|
||||
serviceData.groups.forEach(function (groupName, i) {
|
||||
if (user?.isAdmin && i == 0) {
|
||||
serviceData.groups[i] = {"isAdmin": true};
|
||||
serviceData.groups[i]["displayName"] = groupName;
|
||||
} else {
|
||||
serviceData.groups[i] = {"displayName": groupName};
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Fix OIDC login loop for integer user ID. Thanks to danielkaiser.
|
||||
Meteor.call('groupRoutineOnLogin', serviceData, "" + serviceData.id);
|
||||
Meteor.call('boardRoutineOnLogin', serviceData, "" + serviceData.id);
|
||||
|
||||
return {
|
||||
serviceData: serviceData,
|
||||
options: { profile: profile }
|
||||
};
|
||||
});
|
||||
|
||||
var userAgent = "Meteor";
|
||||
if (Meteor.release) {
|
||||
userAgent += "/" + Meteor.release;
|
||||
}
|
||||
|
||||
if (process.env.ORACLE_OIM_ENABLED !== 'true' && process.env.ORACLE_OIM_ENABLED !== true) {
|
||||
var getToken = function (query) {
|
||||
// Function to retrieve token based on environment
|
||||
var getToken = function (query) {
|
||||
var debug = process.env.DEBUG === 'true';
|
||||
var config = getConfiguration();
|
||||
if(config.tokenEndpoint.includes('https://')){
|
||||
var serverTokenEndpoint = config.tokenEndpoint;
|
||||
}else{
|
||||
var serverTokenEndpoint = config.serverUrl + config.tokenEndpoint;
|
||||
}
|
||||
var requestPermissions = config.requestPermissions;
|
||||
var serverTokenEndpoint = config.tokenEndpoint.includes('https://') ?
|
||||
config.tokenEndpoint : config.serverUrl + config.tokenEndpoint;
|
||||
var response;
|
||||
|
||||
try {
|
||||
var postOptions = {
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
"User-Agent": userAgent
|
||||
},
|
||||
params: {
|
||||
code: query.code,
|
||||
client_id: config.clientId,
|
||||
client_secret: OAuth.openSecret(config.secret),
|
||||
redirect_uri: OAuth._redirectUri('oidc', config),
|
||||
grant_type: 'authorization_code',
|
||||
state: query.state
|
||||
}
|
||||
var postOptions = {
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
"User-Agent": "Meteor"
|
||||
},
|
||||
params: {
|
||||
code: query.code,
|
||||
client_id: config.clientId,
|
||||
client_secret: OAuth.openSecret(config.secret),
|
||||
redirect_uri: OAuth._redirectUri('oidc', config),
|
||||
grant_type: 'authorization_code',
|
||||
state: query.state
|
||||
}
|
||||
};
|
||||
if (httpCa) {
|
||||
postOptions['npmRequestOptions'] = { ca: httpCa };
|
||||
}
|
||||
response = HTTP.post(serverTokenEndpoint, postOptions);
|
||||
if (httpCa) {
|
||||
postOptions['npmRequestOptions'] = { ca: httpCa };
|
||||
}
|
||||
response = HTTP.post(serverTokenEndpoint, postOptions);
|
||||
} catch (err) {
|
||||
throw _.extend(new Error("Failed to get token from OIDC " + serverTokenEndpoint + ": " + err.message),
|
||||
{ response: err.response });
|
||||
throw _.extend(new Error("Failed to get token from OIDC " + serverTokenEndpoint + ": " + err.message),
|
||||
{ response: err.response });
|
||||
}
|
||||
if (response.data.error) {
|
||||
// if the http response was a json object with an error attribute
|
||||
throw new Error("Failed to complete handshake with OIDC " + serverTokenEndpoint + ": " + response.data.error);
|
||||
throw new Error("Failed to complete handshake with OIDC " + serverTokenEndpoint + ": " + response.data.error);
|
||||
} else {
|
||||
if (debug) console.log('XXX: getToken response: ', response.data);
|
||||
return response.data;
|
||||
return response.data;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
if (process.env.ORACLE_OIM_ENABLED === 'true' || process.env.ORACLE_OIM_ENABLED === true) {
|
||||
|
||||
var getToken = function (query) {
|
||||
var debug = process.env.DEBUG === 'true';
|
||||
var config = getConfiguration();
|
||||
if(config.tokenEndpoint.includes('https://')){
|
||||
var serverTokenEndpoint = config.tokenEndpoint;
|
||||
}else{
|
||||
var serverTokenEndpoint = config.serverUrl + config.tokenEndpoint;
|
||||
}
|
||||
var requestPermissions = config.requestPermissions;
|
||||
var response;
|
||||
|
||||
// OIM needs basic Authentication token in the header - ClientID + SECRET in base64
|
||||
var dataToken=null;
|
||||
var strBasicToken=null;
|
||||
var strBasicToken64=null;
|
||||
|
||||
dataToken = process.env.OAUTH2_CLIENT_ID + ':' + process.env.OAUTH2_SECRET;
|
||||
strBasicToken = new Buffer(dataToken);
|
||||
strBasicToken64 = strBasicToken.toString('base64');
|
||||
|
||||
// eslint-disable-next-line no-console
|
||||
if (debug) console.log('Basic Token: ', strBasicToken64);
|
||||
|
||||
try {
|
||||
var postOptions = {
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
"User-Agent": userAgent,
|
||||
"Authorization": "Basic " + strBasicToken64
|
||||
},
|
||||
params: {
|
||||
code: query.code,
|
||||
client_id: config.clientId,
|
||||
client_secret: OAuth.openSecret(config.secret),
|
||||
redirect_uri: OAuth._redirectUri('oidc', config),
|
||||
grant_type: 'authorization_code',
|
||||
state: query.state
|
||||
}
|
||||
};
|
||||
if (httpCa) {
|
||||
postOptions['npmRequestOptions'] = { ca: httpCa };
|
||||
}
|
||||
response = HTTP.post(serverTokenEndpoint, postOptions);
|
||||
} catch (err) {
|
||||
throw _.extend(new Error("Failed to get token from OIDC " + serverTokenEndpoint + ": " + err.message),
|
||||
{ response: err.response });
|
||||
}
|
||||
if (response.data.error) {
|
||||
// if the http response was a json object with an error attribute
|
||||
throw new Error("Failed to complete handshake with OIDC " + serverTokenEndpoint + ": " + response.data.error);
|
||||
} else {
|
||||
// eslint-disable-next-line no-console
|
||||
if (debug) console.log('XXX: getToken response: ', response.data);
|
||||
return response.data;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// Function to fetch user information from the OIDC service
|
||||
var getUserInfo = function (accessToken) {
|
||||
var debug = process.env.DEBUG === 'true';
|
||||
var config = getConfiguration();
|
||||
// Some userinfo endpoints use a different base URL than the authorization or token endpoints.
|
||||
// This logic allows the end user to override the setting by providing the full URL to userinfo in their config.
|
||||
if (config.userinfoEndpoint.includes("https://")) {
|
||||
var serverUserinfoEndpoint = config.userinfoEndpoint;
|
||||
} else {
|
||||
var serverUserinfoEndpoint = config.serverUrl + config.userinfoEndpoint;
|
||||
}
|
||||
var response;
|
||||
try {
|
||||
var getOptions = {
|
||||
headers: {
|
||||
"User-Agent": userAgent,
|
||||
"Authorization": "Bearer " + accessToken
|
||||
}
|
||||
};
|
||||
if (httpCa) {
|
||||
getOptions['npmRequestOptions'] = { ca: httpCa };
|
||||
}
|
||||
response = HTTP.get(serverUserinfoEndpoint, getOptions);
|
||||
} catch (err) {
|
||||
throw _.extend(new Error("Failed to fetch userinfo from OIDC " + serverUserinfoEndpoint + ": " + err.message),
|
||||
{response: err.response});
|
||||
}
|
||||
if (debug) console.log('XXX: getUserInfo response: ', response.data);
|
||||
return response.data;
|
||||
};
|
||||
var debug = process.env.DEBUG === 'true';
|
||||
var config = getConfiguration();
|
||||
var serverUserinfoEndpoint = config.userinfoEndpoint.includes("https://") ?
|
||||
config.userinfoEndpoint : config.serverUrl + config.userinfoEndpoint;
|
||||
|
||||
var getConfiguration = function () {
|
||||
var config = ServiceConfiguration.configurations.findOne({ service: 'oidc' });
|
||||
if (!config) {
|
||||
throw new ServiceConfiguration.ConfigError('Service oidc not configured.');
|
||||
}
|
||||
return config;
|
||||
};
|
||||
|
||||
var getTokenContent = function (token) {
|
||||
var content = null;
|
||||
if (token) {
|
||||
var response;
|
||||
try {
|
||||
var parts = token.split('.');
|
||||
var header = JSON.parse(Buffer.from(parts[0], 'base64').toString());
|
||||
content = JSON.parse(Buffer.from(parts[1], 'base64').toString());
|
||||
var signature = Buffer.from(parts[2], 'base64');
|
||||
var signed = parts[0] + '.' + parts[1];
|
||||
} catch (err) {
|
||||
this.content = {
|
||||
exp: 0
|
||||
};
|
||||
}
|
||||
}
|
||||
return content;
|
||||
}
|
||||
Meteor.methods({
|
||||
'groupRoutineOnLogin': function(info, userId)
|
||||
{
|
||||
check(info, Object);
|
||||
check(userId, String);
|
||||
var propagateOidcData = process.env.PROPAGATE_OIDC_DATA || false;
|
||||
if (propagateOidcData) {
|
||||
users= Meteor.users;
|
||||
user = users.findOne({'services.oidc.id': userId});
|
||||
|
||||
if(user) {
|
||||
//updates/creates Groups and user admin privileges accordingly if not undefined
|
||||
if (info.groups) {
|
||||
addGroupsWithAttributes(user, info.groups);
|
||||
var getOptions = {
|
||||
headers: {
|
||||
"User-Agent": "Meteor",
|
||||
"Authorization": "Bearer " + accessToken
|
||||
}
|
||||
};
|
||||
if (httpCa) {
|
||||
getOptions['npmRequestOptions'] = { ca: httpCa };
|
||||
}
|
||||
response = HTTP.get(serverUserinfoEndpoint, getOptions);
|
||||
} catch (err) {
|
||||
throw _.extend(new Error("Failed to fetch userinfo from OIDC " + serverUserinfoEndpoint + ": " + err.message),
|
||||
{response: err.response});
|
||||
}
|
||||
return response.data;
|
||||
};
|
||||
|
||||
// Function to get the configuration of the OIDC service
|
||||
var getConfiguration = function () {
|
||||
var config = ServiceConfiguration.configurations.findOne({ service: 'oidc' });
|
||||
if (!config) {
|
||||
throw new ServiceConfiguration.ConfigError('Service oidc not configured.');
|
||||
}
|
||||
return config;
|
||||
};
|
||||
|
||||
// Function to decode the token content (JWT)
|
||||
var getTokenContent = function (token) {
|
||||
var content = null;
|
||||
if (token) {
|
||||
try {
|
||||
var parts = token.split('.');
|
||||
var header = JSON.parse(Buffer.from(parts[0], 'base64').toString());
|
||||
content = JSON.parse(Buffer.from(parts[1], 'base64').toString());
|
||||
} catch (err) {
|
||||
content = { exp: 0 };
|
||||
}
|
||||
}
|
||||
return content;
|
||||
}
|
||||
|
||||
// Meteor methods to update groups and boards on login
|
||||
Meteor.methods({
|
||||
'groupRoutineOnLogin': function(info, userId) {
|
||||
check(info, Object);
|
||||
check(userId, String);
|
||||
var propagateOidcData = process.env.PROPAGATE_OIDC_DATA || false;
|
||||
if (propagateOidcData) {
|
||||
users = Meteor.users;
|
||||
user = users.findOne({'services.oidc.id': userId});
|
||||
|
||||
if (user) {
|
||||
if (info.groups) {
|
||||
addGroupsWithAttributes(user, info.groups);
|
||||
}
|
||||
|
||||
if(info.email) addEmail(user, info.email);
|
||||
if(info.fullname) changeFullname(user, info.fullname);
|
||||
if(info.username) changeUsername(user, info.username);
|
||||
}
|
||||
}
|
||||
|
||||
if(info.email) addEmail(user, info.email);
|
||||
if(info.fullname) changeFullname(user, info.fullname);
|
||||
if(info.username) changeUsername(user, info.username);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Meteor.methods({
|
||||
'boardRoutineOnLogin': function(info, oidcUserId)
|
||||
{
|
||||
check(info, Object);
|
||||
check(oidcUserId, String);
|
||||
|
||||
const defaultBoardParams = (process.env.DEFAULT_BOARD_ID || '').split(':');
|
||||
const defaultBoardId = defaultBoardParams.shift()
|
||||
if (!defaultBoardId) return
|
||||
|
||||
const board = Boards.findOne(defaultBoardId)
|
||||
const userId = Users.findOne({ 'services.oidc.id': oidcUserId })?._id
|
||||
const memberIndex = _.pluck(board?.members, 'userId').indexOf(userId);
|
||||
if(!board || !userId || memberIndex > -1) return
|
||||
|
||||
board.addMember(userId)
|
||||
board.setMemberPermission(
|
||||
userId,
|
||||
defaultBoardParams.contains("isAdmin"),
|
||||
defaultBoardParams.contains("isNoComments"),
|
||||
defaultBoardParams.contains("isCommentsOnly"),
|
||||
defaultBoardParams.contains("isWorker")
|
||||
)
|
||||
}
|
||||
});
|
||||
|
||||
Oidc.retrieveCredential = function (credentialToken, credentialSecret) {
|
||||
return OAuth.retrieveCredential(credentialToken, credentialSecret);
|
||||
};
|
||||
'boardRoutineOnLogin': function(info, userId) {
|
||||
check(info, Object);
|
||||
check(userId, String);
|
||||
// Add board updates here if needed
|
||||
}
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue