open-collaboration-server
Version:
Open Collaboration Server implementation, part of the Open Collaboration Tools project
96 lines • 4.05 kB
JavaScript
// ******************************************************************************
// Copyright 2025 TypeFox GmbH
// This program and the accompanying materials are made available under the
// terms of the MIT License, which is available in the project root.
// ******************************************************************************
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
import { OAuthEndpoint, ThirdParty } from './oauth-endpoint.js';
import OAuth2Strategy from 'passport-oauth2';
import { injectable, postConstruct } from 'inversify';
let KeycloakOAuthEndpoint = class KeycloakOAuthEndpoint extends OAuthEndpoint {
id = 'keycloak';
path = '/api/login/keycloak';
redirectPath = '/api/login/keycloak-callback';
label = 'Keycloak';
host;
realm;
clientID;
clientSecret;
userNameClaim;
keycloakBaseUrl;
init() {
this.host = this.configuration.getValue('keycloak-host');
this.realm = this.configuration.getValue('keycloak-realm');
this.clientID = this.configuration.getValue('keycloak-client-id');
this.clientSecret = this.configuration.getValue('keycloak-client-secret');
this.userNameClaim = this.configuration.getValue('keycloak-username-claim');
this.label = this.configuration.getValue('keycloak-client-label') ?? 'Keycloak';
this.keycloakBaseUrl = `${this.host}/realms/${this.realm}`;
}
getProtocolProvider() {
return {
endpoint: this.path,
name: this.label,
type: 'web',
label: {
code: '',
message: this.label,
params: []
},
group: ThirdParty
};
}
shouldActivate() {
return !!this.host && !!this.realm && !!this.clientID;
}
getStrategy(host, port) {
return new KeycloakStrategy({
authorizationURL: `${this.keycloakBaseUrl}/protocol/openid-connect/auth`,
tokenURL: `${this.keycloakBaseUrl}/protocol/openid-connect/token`,
userInfoURL: `${this.keycloakBaseUrl}/protocol/openid-connect/userinfo`,
clientID: this.clientID,
clientSecret: this.clientSecret ?? '',
scope: ['openid', 'email', 'profile'],
callbackURL: this.createRedirectUrl(host, port, this.redirectPath),
}, (accessToken, refreshToken, profile, done) => {
const userInfo = {
name: profile[this.userNameClaim ?? 'preferred_username'],
email: profile.email,
authProvider: this.label,
};
done(undefined, userInfo);
});
}
};
__decorate([
postConstruct()
], KeycloakOAuthEndpoint.prototype, "init", null);
KeycloakOAuthEndpoint = __decorate([
injectable()
], KeycloakOAuthEndpoint);
export { KeycloakOAuthEndpoint };
class KeycloakStrategy extends OAuth2Strategy {
options;
constructor(options, verify) {
super(options, verify);
this.options = options;
}
async userProfile(accessToken, done) {
fetch(this.options.userInfoURL, {
headers: {
Authorization: `Bearer ${accessToken}`,
},
}).then(async (response) => {
if (!response.ok) {
throw new Error(`Failed to fetch user profile: ${response.statusText}`);
}
done(undefined, await response.json());
}).catch(err => done(err));
}
}
//# sourceMappingURL=keycloak-endpoint.js.map