File size: 3,808 Bytes
3b6afc0 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
const passport = require('passport');
const { Issuer, Strategy: OpenIDStrategy } = require('openid-client');
const axios = require('axios');
const fs = require('fs');
const path = require('path');
const config = require('../../config/loader');
const domains = config.domains;
const User = require('../models/User');
let crypto;
try {
crypto = require('node:crypto');
} catch (err) {
console.error('crypto support is disabled!');
}
const downloadImage = async (url, imagePath, accessToken) => {
try {
const response = await axios.get(url, {
headers: {
Authorization: `Bearer ${accessToken}`,
},
responseType: 'arraybuffer',
});
fs.mkdirSync(path.dirname(imagePath), { recursive: true });
fs.writeFileSync(imagePath, response.data);
const fileName = path.basename(imagePath);
return `/images/openid/${fileName}`;
} catch (error) {
console.error(`Error downloading image at URL "${url}": ${error}`);
return '';
}
};
async function setupOpenId() {
try {
const issuer = await Issuer.discover(process.env.OPENID_ISSUER);
const client = new issuer.Client({
client_id: process.env.OPENID_CLIENT_ID,
client_secret: process.env.OPENID_CLIENT_SECRET,
redirect_uris: [domains.server + process.env.OPENID_CALLBACK_URL],
});
const openidLogin = new OpenIDStrategy(
{
client,
params: {
scope: process.env.OPENID_SCOPE,
},
},
async (tokenset, userinfo, done) => {
try {
let user = await User.findOne({ openidId: userinfo.sub });
if (!user) {
user = await User.findOne({ email: userinfo.email });
}
let fullName = '';
if (userinfo.given_name && userinfo.family_name) {
fullName = userinfo.given_name + ' ' + userinfo.family_name;
} else if (userinfo.given_name) {
fullName = userinfo.given_name;
} else if (userinfo.family_name) {
fullName = userinfo.family_name;
} else {
fullName = userinfo.username || userinfo.email;
}
if (!user) {
user = new User({
provider: 'openid',
openidId: userinfo.sub,
username: userinfo.username || userinfo.given_name || '',
email: userinfo.email || '',
emailVerified: userinfo.email_verified || false,
name: fullName,
});
} else {
user.provider = 'openid';
user.openidId = userinfo.sub;
user.username = userinfo.given_name || '';
user.name = fullName;
}
if (userinfo.picture) {
const imageUrl = userinfo.picture;
let fileName;
if (crypto) {
const hash = crypto.createHash('sha256');
hash.update(userinfo.sub);
fileName = hash.digest('hex') + '.png';
} else {
fileName = userinfo.sub + '.png';
}
const imagePath = path.join(
__dirname,
'..',
'..',
'client',
'public',
'images',
'openid',
fileName,
);
const imagePathOrEmpty = await downloadImage(
imageUrl,
imagePath,
tokenset.access_token,
);
user.avatar = imagePathOrEmpty;
} else {
user.avatar = '';
}
await user.save();
done(null, user);
} catch (err) {
done(err);
}
},
);
passport.use('openid', openidLogin);
} catch (err) {
console.error(err);
}
}
module.exports = setupOpenId;
|