oidc-lib
Version:
A library for creating OIDC Service Providers
201 lines (176 loc) • 5.71 kB
JavaScript
module.exports = {
load: load
};
async function load(params, contentModuleName){
var recordClientInfo;
var sub;
var newRecord;
try{
var client_id = params.client_id;
if (client_id === undefined){
throw('mandatory client_id was not specified')
}
try {
if (!params.registration){
var client_info_doc = await pk.dbs['sts'].provider.getDocument(pk.dbs['sts'], 'clients', client_id)
params.registration = client_info_doc;
return(new client_info(client_info_doc));
}
}
catch (err){
//TODO check that err was doc not found
}
if (pk.sts.isSelfIssuedSts()){
var pwkc = pk.pmanager.pairwiseKeyConfig();
var personaKeyObject = new pk.key_management.claimerKeyObject(contentModuleName, pk.key_management.PAIRWISEKEY,
pwkc.kty, pwkc.alg, pwkc.crv);
personaKeyObject.app_role = client_id;
error_message = 'Error in load client_info creating/loading key ';
var personaKeyAndStore = await pk.key_management.createOrLoadSingleKey(personaKeyObject);
var did_method = pk.pmanager.didMethodConfig();
var did = await pk.did_management.create(pk.dbs['sts'], did_method, personaKeyAndStore.keyObject);
sub = did;
recordClientInfo = true;
params.redirect_uri = client_id;
}
else{
var registrationConf = pk.util.config.content_modules[contentModuleName];
if (!registrationConf.acceptUntrustedClients){
throw('Error retrieving client info for ' + client_id);
}
recordClientInfo = false;
}
var registration;
// only valid with self-issued OP
if (params.registration){
try {
var toparse = params.registration.replace(/\+/g, ' ');
registration = JSON.parse(toparse);
}
catch (err){
pk.sts.throw_claimer_error('invalid_request', 'registration parameter is not valid json: ' + params.registration);
}
if (registration.client_id === undefined){
registration.client_id = params.client_id;
}
// TODO: threat model on this
if (params.client_id !== registration.client_id){
pk.sts.throw_claimer_error('invalid_request', 'registration parameter client_id must match request client_id');
}
if (sub){
registration.sub = sub;
}
}
else{
registration = {};
}
registration.client_id = params.client_id;
registration.id = params.client_id;
registration.redirect_uri = params.redirect_uri;
if (registration.redirect_uris === undefined){
registration.redirect_uris = [ registration.redirect_uri ];
}
else if (registration.redirect_uris.indexOf(registration.client_id) < 0){
pk.sts.throw_claimer_error('invalid_request', 'redirect_uri not present in redirect_uris for ' + client_id);
}
if (recordClientInfo){
newRecord = await pk.dbs['sts'].provider.createOrUpdateDocument(pk.dbs['sts'],
'clients', registration);
}
else{
newRecord = registration;
}
if (newRecord){
return(new client_info(newRecord));
}
}
catch(err){
var msg = 'Error loading client_info: ' + err;
throw(msg);
};
}
function client_info(client_info_doc){
var _client_info = client_info_doc;
Object.defineProperty(this, "client_id", {
get: function() {
if (client_info === undefined ||_client_info.client_id === undefined)
pk.sts.throw_claimer_error('invalid_request', "client_id must be supplied but is missing");
return _client_info.client_id;
},
enumerable: true
});
Object.defineProperty(this, "client_name", {
get: function() {
return _client_info.client_name;
},
enumerable: true
});
Object.defineProperty(this, "sub", {
get: function() {
return _client_info.sub;
},
enumerable: true
});
Object.defineProperty(this, "client_secret", {
get: function() {
return _client_info.client_secret;
},
enumerable: true
});
Object.defineProperty(this, "client_uri", {
get: function() {
return _client_info.client_uri;
},
enumerable: true
});
Object.defineProperty(this, "company_logo", {
get: function() {
return _client_info.company_logo;
},
enumerable: true
});
Object.defineProperty(this, "redirect_uri", {
get: function() {
return _client_info.redirect_uri;
},
enumerable: true
});
Object.defineProperty(this, "redirect_uris", {
get: function() {
return _client_info.redirect_uris;
},
enumerable: true
});
Object.defineProperty(this, "signature_info", {
get: function() {
return _client_info.signature_info;
},
enumerable: true
});
this.verify_client_secret = function(secret_to_check){
if (!isset(secret_to_check)){
pk.sts.throw_claimer_error('invalid_request', "client_secret must be supplied but is missing");
}
if (_client_info.client_secret !== secret_to_check){
pk.sts.throw_claimer_error('unauthorized_client nameed ', '\"' + _client_info.client_name + '\" does not have a valid secret');
}
return _client_info.client_secret;
};
this.verify_redirect_uri = function(redirect_uri) {
if (redirect_uri === undefined) {
pk.sts.throw_claimer_error('invalid_request', "redirect_uri must be supplied but is missing");
}
if (_client_info.redirect_uris.indexOf(redirect_uri) < 0){
pk.sts.throw_claimer_error('unauthorized_client', '\"' + redirect_uri + '\" is not a valid redirect_uri for \"' + _client_info.client_id + '\"');
}
// ToDo: verify redirect_uri
return redirect_uri;
}
}
function isset(param){
if (typeof param !== 'object'){
if (param === undefined || param === null || param.length === 0)
return false;
}
return true;
}