@fusebit/everyauth-express
Advanced tools
Comparing version 2.0.2 to 2.1.0
@@ -36,3 +36,3 @@ "use strict"; | ||
const dbg = ({ serviceId, userId, tenantId }, msg) => { | ||
debug(`${serviceId}[${tenantId || ''}${tenantId ? '/' : ''}${userId}]: ${msg}`); | ||
debug(`${serviceId}[${tenantId || ''}${tenantId ? '/' : ''}${userId || 'NA'}]: ${msg}`); | ||
}; | ||
@@ -55,6 +55,8 @@ /** | ||
// Discovery time! | ||
// | ||
// Normalize original URL by removing query | ||
const i = req.originalUrl.indexOf('?'); | ||
const originalUrl = i < 0 ? req.originalUrl : req.originalUrl.substring(0, i); | ||
// Sometimes the originalUrl includes the entire request, sometimes it doesn't! | ||
if (req.originalUrl.startsWith('http')) { | ||
return req.originalUrl; | ||
if (originalUrl.startsWith('http')) { | ||
return originalUrl; | ||
} | ||
@@ -67,3 +69,3 @@ // req.hostname doesn't preserve the port, unfortunately, so test the Host header to see if it's present. | ||
// Return a hopefully valid URL. | ||
return `${req.protocol}://${req.hostname}${port}${req.originalUrl}`; | ||
return `${req.protocol}://${req.hostname}${port}${originalUrl}`; | ||
}; | ||
@@ -103,3 +105,3 @@ exports.getHostedBaseUrl = getHostedBaseUrl; | ||
router.get('/', async (req, res) => { | ||
const userId = await options.mapToUserId(req); | ||
const userId = options.mapToUserId ? await options.mapToUserId(req) : undefined; | ||
const tenantId = options.mapToTenantId ? await options.mapToTenantId(req) : userId; | ||
@@ -129,3 +131,3 @@ const hostedBaseUrl = (0, exports.getHostedBaseUrl)(options, req); | ||
// Update the session object if it's changed | ||
const { identityId, tenantId, userId } = await session.commit(serviceId, sessionId); | ||
const { identityId, tenantId, userId } = await session.commit(req, serviceId, sessionId, options); | ||
dbg({ serviceId, userId, tenantId }, `Success ${identityId}`); | ||
@@ -132,0 +134,0 @@ dbg({ serviceId, userId, tenantId }, `Redirect to ${options.finishedUrl}`); |
@@ -29,3 +29,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.deleteIdentity = exports.getIdentities = exports.getIdentity = void 0; | ||
exports.deleteIdentity = exports.deleteIdentities = exports.getIdentities = exports.getIdentity = void 0; | ||
const superagent = __importStar(require("superagent")); | ||
@@ -67,4 +67,4 @@ const debug_1 = __importDefault(require("debug")); | ||
identities = await getIdentitiesByTags(serviceId, { | ||
[constants_1.USER_TAG]: identityOrIdsOrTags.userId, | ||
[constants_1.TENANT_TAG]: identityOrIdsOrTags.tenantId || identityOrIdsOrTags.userId, | ||
...((identityOrIdsOrTags.userId && { [constants_1.USER_TAG]: identityOrIdsOrTags.userId }) || {}), | ||
...((identityOrIdsOrTags.tenantId && { [constants_1.TENANT_TAG]: identityOrIdsOrTags.tenantId }) || {}), | ||
}); | ||
@@ -103,3 +103,2 @@ } | ||
identities = await getIdentitiesByTags(serviceId, { | ||
[constants_1.SERVICE_TAG]: serviceId, | ||
...('userId' in idsOrTags ? { [constants_1.USER_TAG]: idsOrTags.userId } : {}), | ||
@@ -125,2 +124,22 @@ ...('tenantId' in idsOrTags ? { [constants_1.TENANT_TAG]: idsOrTags.tenantId } : {}), | ||
/** | ||
* Deletes all matching identities. | ||
* | ||
* @param serviceId The service to search for matching identities within. | ||
* @param idsOrTags Either a { userId, tenantId } that can be used to search for a matching identity, or a set of | ||
* tags that will be used to search. Pass 'null' to delete all identities for a service. | ||
*/ | ||
const deleteIdentities = async (serviceId, idsOrTags) => { | ||
if (idsOrTags === undefined || (idsOrTags && Object.keys(idsOrTags).length === 0)) { | ||
throw new Error("The 'idsOrTags' parameter, if not null, must specify at least one identity selection criteria to prevent accidentally deleting all identitites. " + | ||
"If you really want to delete all identities, specify 'null' for 'idsOrTags'."); | ||
} | ||
let options = { count: 10 }; | ||
do { | ||
const identities = await (0, exports.getIdentities)(serviceId, idsOrTags || {}, options); | ||
await Promise.all(identities.items.map((identity) => (0, exports.deleteIdentity)(serviceId, identity.id))); | ||
options = { next: identities.next, count: 10 }; | ||
} while (options.next); | ||
}; | ||
exports.deleteIdentities = deleteIdentities; | ||
/** | ||
* Delete a specified identity. | ||
@@ -127,0 +146,0 @@ * |
@@ -26,3 +26,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.authorize = exports.deleteIdentity = exports.getIdentities = exports.getIdentity = exports.config = exports.session = exports.profile = void 0; | ||
exports.authorize = exports.deleteIdentities = exports.deleteIdentity = exports.getIdentities = exports.getIdentity = exports.config = exports.session = exports.profile = void 0; | ||
exports.profile = __importStar(require("./profile")); | ||
@@ -36,4 +36,5 @@ exports.session = __importStar(require("./session")); | ||
Object.defineProperty(exports, "deleteIdentity", { enumerable: true, get: function () { return identity_1.deleteIdentity; } }); | ||
Object.defineProperty(exports, "deleteIdentities", { enumerable: true, get: function () { return identity_1.deleteIdentities; } }); | ||
var authorize_1 = require("./authorize"); | ||
Object.defineProperty(exports, "authorize", { enumerable: true, get: function () { return authorize_1.authorize; } }); | ||
//# sourceMappingURL=index.js.map |
@@ -45,4 +45,4 @@ "use strict"; | ||
[constants_1.SERVICE_TAG]: tags.serviceId, | ||
[constants_1.USER_TAG]: tags.userId, | ||
[constants_1.TENANT_TAG]: tags.tenantId || tags.userId, | ||
...((tags.userId !== undefined && { [constants_1.USER_TAG]: tags.userId, [constants_1.TENANT_TAG]: tags.userId }) || {}), | ||
...((tags.tenantId !== undefined && { [constants_1.TENANT_TAG]: tags.tenantId }) || {}), | ||
}, '/integration/everyauth', 'install'); | ||
@@ -49,0 +49,0 @@ debug(`${JSON.stringify(tags)}: Found ${installs.items.length} matching installs`); |
@@ -50,4 +50,2 @@ "use strict"; | ||
[constants_1.SERVICE_TAG]: serviceId, | ||
[constants_1.USER_TAG]: userId, | ||
[constants_1.TENANT_TAG]: tenantId || userId, | ||
[constants_1.VERSION_TAG]: version_1.default, | ||
@@ -57,2 +55,8 @@ }, | ||
}; | ||
if (userId) { | ||
payload.tags[constants_1.USER_TAG] = userId; | ||
} | ||
if (tenantId) { | ||
payload.tags[constants_1.TENANT_TAG] = tenantId; | ||
} | ||
// Is there an existing matching user? | ||
@@ -82,8 +86,24 @@ payload.installId = await (0, install_1.getInstallIdByTags)({ serviceId, userId, tenantId }); | ||
exports.get = get; | ||
const commit = async (serviceId, sessionId) => { | ||
const commit = async (req, serviceId, sessionId, options) => { | ||
const profile = await (0, profile_1.getAuthedProfile)(); | ||
const baseUrl = getSessionUrl(profile); | ||
debug(`${sessionId}: committing`); | ||
// Invoke callback if provided | ||
if (options.onAuthorized) { | ||
const result = await superagent | ||
.get(`${baseUrl}/session/${sessionId}/`) | ||
.set('User-Agent', version_1.default) | ||
.set('Authorization', `Bearer ${profile.accessToken}`); | ||
const ctx = { | ||
serviceId, | ||
tags: result.body.tags, | ||
}; | ||
await options.onAuthorized(req, ctx); | ||
} | ||
let result = await superagent | ||
.get(`${baseUrl}/session/${sessionId}/`) | ||
.set('User-Agent', version_1.default) | ||
.set('Authorization', `Bearer ${profile.accessToken}`); | ||
// Start the commit process | ||
let result = await superagent | ||
result = await superagent | ||
.post(`${baseUrl}/session/${sessionId}/commit`) | ||
@@ -93,3 +113,3 @@ .set('User-Agent', version_1.default) | ||
.send(); | ||
// Get the session while the commit is going to grab the tenant id; try multiple times in case there's a | ||
// Get the session while the commit is going to grab the installId; try multiple times in case there's a | ||
// race. | ||
@@ -96,0 +116,0 @@ do { |
@@ -42,6 +42,2 @@ "use strict"; | ||
} | ||
// eslint-disable-next-line security/detect-object-injection | ||
if (!tags[constants_1.USER_TAG]) { | ||
throw new Error(`Missting tag ${constants_1.USER_TAG}`); | ||
} | ||
// Convert the IEveryAuthTagSet into the right query parameters | ||
@@ -67,4 +63,4 @@ const params = new URLSearchParams(); | ||
} | ||
if (options.pageSize) { | ||
params.set('pageSize', `${options.pageSize}`); | ||
if (options.count) { | ||
params.set('count', `${options.count}`); | ||
} | ||
@@ -71,0 +67,0 @@ } |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.default = `${process.env.EVERYAUTH_VERSION_PREFIX}everyauth-express/${require('../package.json').version}`; | ||
exports.default = `${process.env.EVERYAUTH_VERSION_PREFIX || ''}everyauth-express/${require('../package.json').version}`; | ||
//# sourceMappingURL=version.js.map |
{ | ||
"name": "@fusebit/everyauth-express", | ||
"version": "2.0.2", | ||
"version": "2.1.0", | ||
"description": "EveryAuth is the easiest way for your app to access APIs like Slack, Salesforce, or Github.", | ||
@@ -24,3 +24,3 @@ "main": "libc/index.js", | ||
}, | ||
"author": "", | ||
"author": "Fusebit, Inc", | ||
"license": "ISC", | ||
@@ -27,0 +27,0 @@ "bugs": { |
@@ -416,4 +416,4 @@ # EveryAuth | ||
| `serviceId` | string | The name of the remote service the user should be authenicated with. | | ||
| `tags` | Record<string,<br/> string \|<br/> number \|<br/> undefined \|<br/> null| A set of tags returned identities must have. | | ||
| `options` | object (optional) | Specify the `next` property as returned by a previous call to `getIdentities` to get a next page of matching identities. Specify the `pageSize` property to indicate the desired maximum number of results to return. | | ||
| `idsOrTags` | Record<string,<br/> string \|<br/> number \|<br/> undefined \|<br/> null| A set of tags returned identities must have. | | ||
| `options` | object (optional) | Specify the `next` property as returned by a previous call to `getIdentities` to get a next page of matching identities. Specify the `count` property to indicate the desired maximum number of results to return. | | ||
@@ -427,2 +427,40 @@ ##### Return <!-- omit in toc --> | ||
#### deleteIdentity(serviceId, identityId) | ||
Deletes an existing identity. | ||
```javascript | ||
import everyauth from "@fusebit/everyauth-express"; | ||
// Delete single identity | ||
const identity = await everyauth.getIdentity("slack", { userId }); | ||
await everyauth.deleteIdentity("slack", identity.fusebit.identityId); | ||
``` | ||
##### Parameters <!-- omit in toc --> | ||
| name | type | description | | ||
|------|------|-------------| | ||
| `serviceId` | string | The name of the remote service the user should be authenticated with. | | ||
| `identityId` | string | The identity ID returned as part of `getIdentity` or `getIdentities` call. | | ||
#### deleteIdentities(serviceId, identityId) | ||
Deletes all identities matching the search criteria. | ||
```javascript | ||
import everyauth from "@fusebit/everyauth-express"; | ||
// Delete all identities tagged with tenantId 'contoso' | ||
const tenantId = "contoso"; | ||
await everyauth.deleteIdentities("slack", { tenantId }); | ||
``` | ||
##### Parameters <!-- omit in toc --> | ||
| name | type | description | | ||
|------|------|-------------| | ||
| `serviceId` | string | The name of the remote service to delete identities of. | | ||
| `idsOrTagsOrNull` | Record<string,<br/> string \|<br/> number \|<br/> undefined \|<br/> null | A set of tags identities to be deleted must have. Specify `null` if you want to delete all identities of the service. | | ||
#### EveryAuthOptions | ||
@@ -436,3 +474,11 @@ | ||
| `mapToTenantId` | async (req: [Express.request](https://expressjs.com/en/api.html#req)) => string | This method is called to generate a string tenant id to identify the tenant in your system, and allow querying EveryAuth for credentials owned by that tenant. If you don't specify this callback, the value of the tenant id will be set to the same value as the user id. | | ||
| `onCompleted` | async (req: [Express.request](https://expressjs.com/en/api.html#req), ctx: [IEveryAuthAuthorizedContext](#ieveryauthauthorizedcontext)) => void | Called after a user successfully authorized to a target service but before their identity has been persisted. Perform any side-effect operations like removing prior identities that are no longer needed. | | ||
#### IEveryAuthAuthorizedContext | ||
| name | type | description | | ||
|------|------|-------------| | ||
| `serviceId` | string | The name of the remote service the user authorized to. | | ||
| `tags` | object | A set of tags associated with the established identity. | | ||
#### IEveryAuthCredential | ||
@@ -439,0 +485,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No contributors or author data
MaintenancePackage does not specify a list of contributors or an author in package.json.
Found 1 instance in 1 package
93939
889
0
524