197 lines
5.9 KiB
JavaScript
197 lines
5.9 KiB
JavaScript
;(function (exports) {
|
|
'use strict';
|
|
|
|
var core = window.OAUTH3_CORE;
|
|
|
|
// Provider-Only
|
|
core.urls.loginCode = function (directive, opts) {
|
|
//
|
|
// Example Resource Owner Password Request
|
|
// (generally for 1st party and direct-partner mobile apps, and webapps)
|
|
//
|
|
// POST https://api.example.com/api/org.oauth3.provider/otp
|
|
// { "request_otp": true, "client_id": "<<id>>", "scope": "<<scope>>"
|
|
// , "username": "<<username>>" }
|
|
//
|
|
opts = opts || {};
|
|
var clientId = opts.appId || opts.clientId;
|
|
|
|
var args = directive.credential_otp;
|
|
if (!directive.credential_otp) {
|
|
console.log('[debug] loginCode directive:');
|
|
console.log(directive);
|
|
}
|
|
var params = {
|
|
"username": opts.id || opts.username
|
|
, "request_otp": true // opts.requestOtp || undefined
|
|
//, "jwt": opts.jwt // TODO sign a proof
|
|
, debug: opts.debug || undefined
|
|
};
|
|
var uri = args.url;
|
|
var body;
|
|
if (opts.clientUri) {
|
|
params.client_uri = opts.clientUri;
|
|
}
|
|
if (opts.clientAgreeTos) {
|
|
params.client_agree_tos = opts.clientAgreeTos;
|
|
}
|
|
if (clientId) {
|
|
params.client_id = clientId;
|
|
}
|
|
if ('GET' === args.method.toUpperCase()) {
|
|
uri += '?' + core.querystringify(params);
|
|
} else {
|
|
body = params;
|
|
}
|
|
|
|
return {
|
|
url: uri
|
|
, method: args.method
|
|
, data: body
|
|
};
|
|
};
|
|
|
|
core.urls.resourceOwnerPassword = function (directive, opts) {
|
|
//
|
|
// Example Resource Owner Password Request
|
|
// (generally for 1st party and direct-partner mobile apps, and webapps)
|
|
//
|
|
// POST https://example.com/api/org.oauth3.provider/access_token
|
|
// { "grant_type": "password", "client_id": "<<id>>", "scope": "<<scope>>"
|
|
// , "username": "<<username>>", "password": "password" }
|
|
//
|
|
opts = opts || {};
|
|
var type = 'access_token';
|
|
var grantType = 'password';
|
|
|
|
if (!opts.password) {
|
|
if (opts.otp) {
|
|
// for backwards compat
|
|
opts.password = opts.otp; // 'otp:' + opts.otpUuid + ':' + opts.otp;
|
|
}
|
|
}
|
|
|
|
var scope = opts.scope || directive.authn_scope;
|
|
var clientId = opts.appId || opts.clientId || opts.client_id;
|
|
var clientAgreeTos = opts.clientAgreeTos || opts.client_agree_tos;
|
|
var clientUri = opts.clientUri || opts.client_uri || opts.clientUrl || opts.client_url;
|
|
var args = directive[type];
|
|
var otpCode = opts.otp || opts.otpCode || opts.otp_code || opts.otpToken || opts.otp_token || undefined;
|
|
var params = {
|
|
"grant_type": grantType
|
|
, "username": opts.username
|
|
, "password": opts.password || otpCode || undefined
|
|
, "totp": opts.totp || opts.totpToken || opts.totp_token || undefined
|
|
, "otp": otpCode
|
|
, "password_type": otpCode && 'otp'
|
|
, "otp_code": otpCode
|
|
, "otp_uuid": opts.otpUuid || opts.otp_uuid || undefined
|
|
, "user_agent": opts.userAgent || opts.useragent || opts.user_agent || undefined // AJ's Macbook
|
|
, "jwk": (opts.rememberDevice || opts.remember_device) && opts.jwk || undefined
|
|
//, "public_key": opts.rememberDevice && opts.publicKey || undefined
|
|
//, "public_key_type": opts.rememberDevice && opts.publicKeyType || undefined // RSA/ECDSA
|
|
//, "jwt": opts.jwt // TODO sign a proof with a previously loaded public_key
|
|
, debug: opts.debug || undefined
|
|
};
|
|
var uri = args.url;
|
|
var body;
|
|
if (opts.totp) {
|
|
params.totp = opts.totp;
|
|
}
|
|
|
|
if (clientId) {
|
|
params.clientId = clientId;
|
|
}
|
|
if (clientUri) {
|
|
params.clientUri = clientUri;
|
|
params.clientAgreeTos = clientAgreeTos;
|
|
if (!clientAgreeTos) {
|
|
throw new Error('Developer Error: missing clientAgreeTos uri');
|
|
}
|
|
}
|
|
|
|
if (scope) {
|
|
params.scope = core.stringifyscope(scope);
|
|
}
|
|
|
|
if ('GET' === args.method.toUpperCase()) {
|
|
uri += '?' + core.querystringify(params);
|
|
} else {
|
|
body = params;
|
|
}
|
|
|
|
return {
|
|
url: uri
|
|
, method: args.method
|
|
, data: body
|
|
};
|
|
};
|
|
|
|
|
|
core.urls.grants = function (directive, opts) {
|
|
// directive = { issuer, authorization_decision }
|
|
// opts = { response_type, scopes{ granted, requested, pending, accepted } }
|
|
|
|
if (!opts) {
|
|
throw new Error("You must supply a directive and an options object.");
|
|
}
|
|
if (!opts.client_id) {
|
|
throw new Error("You must supply options.client_id.");
|
|
}
|
|
if (!opts.session) {
|
|
throw new Error("You must supply options.session.");
|
|
}
|
|
if (!opts.referrer) {
|
|
console.warn("You should supply options.referrer");
|
|
}
|
|
if (!opts.method) {
|
|
console.warn("You must supply options.method as either 'GET', or 'POST'");
|
|
}
|
|
if ('POST' === opts.method && !opts.scope) {
|
|
console.warn("You must supply options.scope as a space-delimited string of scopes");
|
|
}
|
|
|
|
var url = core.urls.resolve(directive.issuer, directive.grants.url)
|
|
.replace(/(:azp|:client_id)/g, opts.client_id || opts.client_uri)
|
|
.replace(/(:sub|:account_id)/g, opts.session.meta.sub)
|
|
;
|
|
var data = {
|
|
client_id: opts.client_id
|
|
, client_uri: opts.client_uri
|
|
, referrer: opts.referrer
|
|
, response_type: opts.response_type
|
|
, scope: opts.scope
|
|
, tenant_id: opts.tenant_id
|
|
};
|
|
var body;
|
|
|
|
if ('GET' === opts.method) {
|
|
url += '?' + core.querystringify(data);
|
|
}
|
|
else {
|
|
body = data;
|
|
}
|
|
|
|
return {
|
|
method: opts.method
|
|
, url: url
|
|
, data: body
|
|
, session: opts.session
|
|
};
|
|
};
|
|
core.urls.authorizationDecision = function (directive, opts) {
|
|
var url = core.urls.resolve(directive.issuer, directive.authorization_decision.url);
|
|
if (!opts) {
|
|
throw new Error("You must supply a directive and an options object");
|
|
}
|
|
console.info(url);
|
|
throw new Error("NOT IMPLEMENTED authorization_decision");
|
|
};
|
|
|
|
exports.OAUTH3_CORE_PROVIDER = core;
|
|
|
|
if ('undefined' !== typeof module) {
|
|
module.exports = core;
|
|
}
|
|
}('undefined' !== typeof exports ? exports : window));
|