Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

auth0-ext-compilers

Package Overview
Dependencies
Maintainers
3
Versions
12
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

auth0-ext-compilers - npm Package Compare versions

Comparing version 4.0.0 to 5.0.0

92

lib/adapter.js
'use strict';
const Errors = require('./errors');
module.exports = {
respondWithError,
wrap,

@@ -11,2 +10,44 @@ };

function respondWithError(error, res) {
if (!(error instanceof Error)) {
error = new Error(error.message || String(error) || 'Unknown error')
}
if (!error.statusCode) {
error.statusCode = 500;
}
const statusCode = error.statusCode;
const headers = {
'Content-Type': 'application/json',
};
const payload = {
message: error.message,
statusCode: error.statusCode,
}
['code', 'errno', 'error', 'error_description', 'data']
.forEach(key => {
if (error[key]) payload[key] = error[key];
});
if (error.statusCode === 500 && error.stack) {
payload.stack = error.stack;
}
let json;
try {
json = JSON.stringify(payload);
} catch (e) {
const error = new Error('Error serializing error: ' + e.message);
error.statusCode = 500;
return respondWithError(error, res);
}
res.writeHead(statusCode, headers);
res.end(json);
}
function wrap(webtaskFn, payloadAdapter) {

@@ -26,40 +67,33 @@ if (!payloadAdapter) {

function buildResponse(error /*, arg1, arg2, ...*/) {
if (error) {
return respondWithError(error, res);
}
const response = {
statusCode: 200,
headers: {
'Content-Type': 'application/json',
},
}
if (error) {
response.statusCode = error.statusCode || 500;
response.data = {
message: error.message || 'Unkown error',
code: error.code || 'unknown_error',
statusCode: error.statusCode || 500,
stack: error.stack,
};
} else {
headers: { },
// Marshall the non-error callback arguments into the wire format
// that the extension <--> auth0-server protocol expects
response.data = payloadAdapter.apply(null, Array.prototype.slice.call(arguments, 1));
data: payloadAdapter.apply(null, Array.prototype.slice.call(arguments, 1)),
}
return respond(response);
}
// Currently the respond function assumes json as the only format that
// will be sent over the wire. In the future we could inspect the request
// and do applicable content negotiation.
function respond(response) {
// Currently the respond function assumes json as the only format that
// will be sent over the wire. In the future we could inspect the request
// and do applicable content negotiation.
let json;
try {
const body = JSON.stringify(response.data);
res.writeHead(response.statusCode, response.headers);
res.end(body);
json = JSON.stringify(response.data);
} catch (e) {
return buildResponse(Errors.badImplementation('Error when JSON serializing the result of the extension point'));
return respondWithError(new Error('Error when JSON serializing the result of the extension point'), res);
}
response.headers['Content-Type'] = 'application/json';
res.writeHead(response.statusCode, response.headers);
res.end(json);
return;
}
}
}
'use strict';
const Errors = require('./errors');
module.exports = {

@@ -16,5 +14,9 @@ is_authorized,

if (match && match[1] === ctx.secrets['auth0-extension-secret']) return cb();
return cb(Errors.unauthorized());
const error = new Error('Unauthorized extensibility point');
error.statusCode = 401;
return cb(error);
}
return cb();
}

@@ -5,11 +5,22 @@ 'use strict';

const Authz = require('../authorization');
const Errors = require('../errors');
module.exports = authorize_and_process_body;
module.exports = clientCredentialsExchange;
function authorize_and_process_body(options, cb) {
function clientCredentialsExchange(options, cb) {
options.nodejsCompiler(options.script, function (error, func) {
if (error) return cb(error);
if (error) {
// Return a wrapped webtask function that will generate an error
// so that we have a consistent pathway to error reporting
const webtaskFn = (webtaskContext, cb) => {
error.error_description = error.message;
error.message = 'Unable to compile the extensibility code as javascript';
return cb(error);
};
return cb(null, Adapter.wrap(webtaskFn));
}

@@ -21,13 +32,13 @@

function handler (webtaskContext, cb) {
Authz.is_authorized(webtaskContext, err => {
if (err) return cb(err);
Authz.is_authorized(webtaskContext, error => {
if (error) return cb(error);
if (typeof webtaskContext.body !== 'object')
return cb(Errors.badRequest());
return cb(new Error('Body received by extensibility point is not an object'));
if (typeof webtaskContext.body.client !== 'object')
return cb(Errors.badRequest());
return cb(new Error('Body .client received by extensibility point is not an object'));
if (webtaskContext.body.scope && !Array.isArray(webtaskContext.body.scope))
return cb(Errors.badRequest());
return cb(new Error('Body .scope received by extensibility point is neither empty nor an array'));
if (typeof webtaskContext.body.audience !== 'string')
return cb(Errors.badRequest());
return cb(new Error('Body .audience received by extensibility point is not a string'));

@@ -34,0 +45,0 @@ const context = typeof webtaskContext.body.context === 'object'

@@ -5,3 +5,2 @@ 'use strict';

const Authz = require('../authorization');
const Errors = require('../errors');

@@ -23,13 +22,5 @@

function rawHandler(ctx, req, res) {
Authz.is_authorized(ctx, err => {
if (err) {
res.writeHead(err.statusCode || 500, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({
message: err.message || 'Unkown error',
code: err.code || 'unknown_error',
statusCode: err.statusCode || 500,
stack: err.stack,
}));
return;
Authz.is_authorized(ctx, error => {
if (error) {
return Adapter.respondWithError(error, res);
}

@@ -36,0 +27,0 @@

@@ -8,3 +8,3 @@ {

},
"version": "4.0.0",
"version": "5.0.0",
"description": "Webtask compilers for Auth0 platform extensibility points",

@@ -11,0 +11,0 @@ "engines": {

@@ -11,6 +11,8 @@ This repository contains [webtask compilers](https://webtask.io/docs/webtask-compilers) that enable custom programming models for Auth0 platform extensibility points.

cat > custom_claims.js <<EOF
module.exports = function (ctx, cb) {
ctx.scope.push('foo');
ctx['https://example.com/foo'] = 'bar';
cb(null, ctx);
module.exports = function(client, scope, audience, context, cb) {
var access_token = {};
access_token['https://foo.com/claim'] = 'bar';
access_token.scope = scope;
access_token.scope.push('extra');
cb(null, access_token);
};

@@ -29,5 +31,5 @@ EOF

## What is Auth0 extension
## What is an Auth0 extension
Auth0 extension is a webtask created in the Auth0 tenant's webtask container and associated with specific metadata properties as outlined in the table below.
An Auth0 extension is a webtask created in the Auth0 tenant's webtask container and associated with specific metadata properties as outlined in the table below.

@@ -46,3 +48,3 @@ | Name | Required? | Value |

Auth0 extensions are executed by issuing an HTTP POST request to the webtask URL from Auth0 runtime. To ensure only Auth0 runtime and/or a specific Auth0 tenant can issue such requests, the requests use a secret-based authorization mechanism. If an extension webtask has been created with `auth0-extension-secret` secret parameter, the value of that parameter MUST equal to the value of the `Authorization: Bearer {secret}` header of the HTTP POST request. To allow Auth0 runtime to add the necessary header to the webtask request it is making, the same secret value is stored in the `auth0-extension-secret` metadata property. This setup can be achieved with the following:
Auth0 extensions are executed by issuing an HTTP POST request to the webtask URL from the Auth0 runtime. To ensure that only the Auth0 runtime and/or a specific Auth0 tenant can issue such requests, the requests use a secret-based authorization mechanism. If an extension webtask has been created with the `auth0-extension-secret` secret parameter, the value of that parameter MUST equal to the value of the `Authorization: Bearer {secret}` header of the HTTP POST request. To allow the Auth0 runtime to add the necessary header to the webtask request it is making, the same secret value is stored in the `auth0-extension-secret` metadata property. This setup can be achieved with the following:

@@ -120,8 +122,43 @@ ```bash

@param {string} audience - token's audience claim
@param {object} context - additional authorization context
@param {object} context.webtask - the raw webtask context object
@param {function} cb - function (error, accessTokenClaims)
*/
module.exports = function (client, scope, audience, cb) {
// add any namespaced claims directly to ctx
module.exports = function (client, scope, audience, context cb) {
// call the callback with an error to signal authorization failure
// or with a mapping of claims to values (including scopes).
cb(null, { claim: 'value' }); // return error or a mapping of access token claims
};
```
### The *generic* programming model for all extensibility points
A generic compiler is provided (`auth0-ext-compilers/generic`) that does not adhere to any extension-specific programming model. Instead, this compiler is a light facade on top of the 2ary and 3ary [webtask programming models](https://webtask.io/docs/model). The compiler provides authorization of the incoming webtask request and then invokes the supplied function.
#### 2ary *generic* extension
```javascript
module.exports = function(ctx, cb) {
var scope = ctx.body.scope;
var access_token = {};
access_token['https://foo.com/claim'] = 'bar';
access_token.scope = scope;
access_token.scope.push('extra');
cb(null, access_token);
};
```
#### 3ary *generic* extension
```javascript
module.exports = function(ctx, req, res) {
var scope = ctx.body.scope;
var access_token = {};
access_token['https://foo.com/claim'] = 'bar';
access_token.scope = scope;
access_token.scope.push('extra');
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify(access_token));
};
```

@@ -91,3 +91,3 @@ 'use strict';

Assert.ok(error);
Assert.equal(error.statusCode, 401);
Assert.equal(error.status, 401);
Assert.equal(data, undefined);

@@ -111,3 +111,3 @@ done();

Assert.ok(error);
Assert.equal(error.statusCode, 401);
Assert.equal(error.status, 401);
Assert.equal(data, undefined);

@@ -259,3 +259,3 @@ done();

Assert.ok(error);
Assert.equal(error.statusCode, 400);
Assert.equal(error.status, 400);
Assert.equal(data, undefined);

@@ -278,3 +278,3 @@ done();

Assert.ok(error);
Assert.equal(error.statusCode, 400);
Assert.equal(error.status, 400);
Assert.equal(data, undefined);

@@ -297,3 +297,3 @@ done();

Assert.ok(error);
Assert.equal(error.statusCode, 400);
Assert.equal(error.status, 400);
Assert.equal(data, undefined);

@@ -316,3 +316,3 @@ done();

Assert.ok(error);
Assert.equal(error.statusCode, 400);
Assert.equal(error.status, 400);
Assert.equal(data, undefined);

@@ -336,3 +336,3 @@ done();

Assert.ok(error);
Assert.equal(error.statusCode, 401);
Assert.equal(error.status, 401);
Assert.equal(data, undefined);

@@ -356,3 +356,3 @@ done();

Assert.ok(error);
Assert.equal(error.statusCode, 401);
Assert.equal(error.status, 401);
Assert.equal(data, undefined);

@@ -369,2 +369,3 @@ done();

try {
// For brevity ;-)
var factory = eval('(function (module) {' + script + '})');

@@ -396,6 +397,11 @@ var m = { exports: {} };

error.code = payload.code;
error.statusCode = payload.statusCode;
error.stack = payload.stack;
error.title = payload.title;
error.status = payload.status;
error.detail = payload.detail;
for (let key in payload) {
if (!error[key]) {
error[key] = payload[key];
}
}
return cb(error);

@@ -402,0 +408,0 @@ }

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc