@microsoft/teams.apps
Version:
<p> <a href="https://www.npmjs.com/package/@microsoft/teams.apps" target="_blank"> <img src="https://img.shields.io/npm/v/@microsoft/teams.apps/latest" /> </a> <a href="https://www.npmjs.com/package/@microsoft/teams.apps?activeTab=code
155 lines • 12.2 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.OAuthFlowRegistry = void 0;
const constants_1 = require("../diagnostics/constants");
const handlers_1 = require("./handlers");
const telemetry_1 = require("./telemetry");
const _1 = require(".");
/**
* Owns either the legacy default OAuth flow or registered flows.
*/
class OAuthFlowRegistry {
flows = new Map();
usesRegisteredFlows;
/**
* Creates the registry and installs routes for all flows.
*
* Omitting `defaultConnectionName` starts the registry in registered-flow mode.
*/
constructor(options) {
this.usesRegisteredFlows = options.defaultConnectionName === undefined;
if (options.defaultConnectionName !== undefined) {
const defaultFlow = new _1.OAuthFlow(options.defaultConnectionName);
this.flows.set(this.normalize(defaultFlow.connectionName), defaultFlow);
}
this.registerRoutes(options);
}
/**
* Adds a flow. The first registration removes the legacy
* implicit flow; subsequent additions of the same name are rejected.
*/
add(flow) {
if (!this.usesRegisteredFlows) {
this.flows.clear();
this.usesRegisteredFlows = true;
}
const normalized = this.normalize(flow.connectionName);
if (this.flows.has(normalized)) {
throw new Error(`An OAuth flow is already registered for connection "${flow.connectionName}".`);
}
this.flows.set(normalized, flow);
}
/**
* Resolves a flow by connection name.
*/
get(connectionName) {
if (!connectionName.trim()) {
throw new Error('OAuth connection name is required.');
}
const normalized = this.normalize(connectionName);
const flow = this.flows.get(normalized);
if (flow) {
return flow;
}
const available = this.getAll()
.map(item => item.connectionName)
.join(', ');
throw new Error(`No OAuth flow is registered for connection "${connectionName}". ` +
`Registered connections: ${available || '(none)'}.`);
}
/** Returns every flow in the active legacy or registered-flow mode. */
getAll() {
return [...this.flows.values()];
}
/**
* Gets and corrects token-service status for every registered connection.
*
* Silent SSO can leave the status endpoint stale, so disconnected or omitted
* flows are checked directly for a cached token.
*/
async getConnectionStatus(context) {
const flows = this.getAll();
if (flows.length === 0) {
throw new Error('No OAuth flow is registered. Call addOAuthFlow(connectionName) on the App first.');
}
return (0, telemetry_1.traceOAuthOperation)(constants_1.APP_SPAN_NAMES.oauth, constants_1.APP_OAUTH_ALL_CONNECTIONS, constants_1.APP_OAUTH_OPERATION.connectionStatus, async (_span, telemetry) => {
const statuses = await context.api.users.getTokenStatus({
channelId: context.activity.channelId,
userId: context.activity.from.id,
includeFilter: '',
});
const results = statuses.map(status => ({ ...status }));
for (const flow of flows) {
const existing = results.find(status => this.normalize(status.connectionName) ===
this.normalize(flow.connectionName));
if (existing?.hasToken) {
continue;
}
const token = await flow.getToken(context);
if (!token) {
continue;
}
if (existing) {
existing.hasToken = true;
}
else {
results.push({
channelId: context.activity.channelId,
connectionName: flow.connectionName,
hasToken: true,
serviceProviderDisplayName: '',
});
}
}
telemetry.result = constants_1.APP_OAUTH_RESULT.success;
return results;
});
}
/**
* Validates a connection before a deprecated context OAuth helper runs.
*/
validate(connectionName, connectionNameProvided) {
if (!this.usesRegisteredFlows) {
return;
}
if (!connectionNameProvided) {
throw new Error('OAuth connection name is required when OAuth flows are registered.');
}
this.get(connectionName);
}
/**
* Records pending attribution for a flow.
*/
recordPending(context, connectionName, supportsSso) {
if (!this.usesRegisteredFlows) {
return;
}
this.get(connectionName).recordPending(context, supportsSso);
}
registerRoutes(options) {
const handlers = new handlers_1.OauthHandlers(() => this.getAll(), options.client, options.events, options.graphBaseUrl, () => this.usesRegisteredFlows);
options.router.register({
name: 'signin.token-exchange',
type: 'system',
select: activity => activity.type === 'invoke' && activity.name === 'signin/tokenExchange',
callback: ctx => handlers.onTokenExchange(ctx),
});
options.router.register({
name: 'signin.verify-state',
type: 'system',
select: activity => activity.type === 'invoke' && activity.name === 'signin/verifyState',
callback: ctx => handlers.onVerifyState(ctx),
});
options.router.register({
name: 'signin.failure',
type: 'system',
select: activity => activity.type === 'invoke' && activity.name === 'signin/failure',
callback: ctx => handlers.onSignInFailure(ctx),
});
}
normalize(connectionName) {
return connectionName.trim().toLowerCase();
}
}
exports.OAuthFlowRegistry = OAuthFlowRegistry;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVnaXN0cnkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvb2F1dGgvcmVnaXN0cnkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBSUEsd0RBS2tDO0FBS2xDLHlDQUEyQztBQUMzQywyQ0FBa0Q7QUFFbEQsd0JBQThCO0FBVTlCOztHQUVHO0FBQ0gsTUFBYSxpQkFBaUI7SUFDWCxLQUFLLEdBQUcsSUFBSSxHQUFHLEVBQThCLENBQUM7SUFDdkQsbUJBQW1CLENBQVU7SUFFckM7Ozs7T0FJRztJQUNILFlBQVksT0FBMEM7UUFDcEQsSUFBSSxDQUFDLG1CQUFtQixHQUFHLE9BQU8sQ0FBQyxxQkFBcUIsS0FBSyxTQUFTLENBQUM7UUFDdkUsSUFBSSxPQUFPLENBQUMscUJBQXFCLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDaEQsTUFBTSxXQUFXLEdBQUcsSUFBSSxZQUFTLENBQVUsT0FBTyxDQUFDLHFCQUFxQixDQUFDLENBQUM7WUFDMUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxXQUFXLENBQUMsY0FBYyxDQUFDLEVBQUUsV0FBVyxDQUFDLENBQUM7UUFDMUUsQ0FBQztRQUNELElBQUksQ0FBQyxjQUFjLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDL0IsQ0FBQztJQUVEOzs7T0FHRztJQUNILEdBQUcsQ0FBQyxJQUF3QjtRQUMxQixJQUFJLENBQUMsSUFBSSxDQUFDLG1CQUFtQixFQUFFLENBQUM7WUFDOUIsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNuQixJQUFJLENBQUMsbUJBQW1CLEdBQUcsSUFBSSxDQUFDO1FBQ2xDLENBQUM7UUFFRCxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsQ0FBQztRQUN2RCxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxFQUFFLENB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