Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
9fc0b60
migrate .net change in for adding oauth app credentials as a parameter
lzc850612 Feb 12, 2020
5303ebe
rename variable
lzc850612 Feb 12, 2020
aa0f2a9
change turn state key name
lzc850612 Feb 12, 2020
e96d586
fix use ternary operator
lzc850612 Feb 12, 2020
fa3a8fb
Merge remote-tracking branch 'origin/master' into tedlee/implement-oa…
lzc850612 Feb 12, 2020
c0e7a7c
use CredentialTokenProvider interface that extends UserTokenProvider …
lzc850612 Feb 12, 2020
108ce3c
remove unused comments
lzc850612 Feb 12, 2020
043a86d
correct the credentialTokenProvider interface path
lzc850612 Feb 12, 2020
86d8f83
fix import
lzc850612 Feb 12, 2020
fdf30df
fix the dependency chain
lzc850612 Feb 14, 2020
d1ffb7a
fix parameter name
lzc850612 Feb 14, 2020
14854dc
Merge remote-tracking branch 'origin/master' into tedlee/implement-oa…
lzc850612 Feb 18, 2020
87c5adc
fix comments
lzc850612 Feb 25, 2020
9c5f2d5
Merge remote-tracking branch 'origin/master' into tedlee/implement-oa…
lzc850612 Feb 25, 2020
b415187
fix tests
lzc850612 Feb 26, 2020
ca09f58
fix token resolve test
lzc850612 Feb 26, 2020
f1fa070
fix test
lzc850612 Feb 26, 2020
e1ff0cf
Merge branch 'master' into tedlee/implement-oauth-credentials
lzc850612 Feb 26, 2020
e26a857
Merge branch 'master' into tedlee/implement-oauth-credentials
lzc850612 Feb 26, 2020
9fc09bd
added getSignInLink overload
Feb 26, 2020
2baab65
- Merge branch 'master' into oauthOverloads
Feb 28, 2020
40dba82
Merge branch 'master' into oauthOverloads
mdrichardson Feb 28, 2020
72c94c8
remove accidental merge file
Feb 28, 2020
e5bafaf
Merge branch 'oauthOverloads' of https://github.com/microsoft/botbuil…
Feb 28, 2020
1fb8b10
Merge branch 'master' into oauthOverloads
mdrichardson Feb 28, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions libraries/botbuilder/src/botFrameworkAdapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -581,10 +581,14 @@ export class BotFrameworkAdapter extends BotAdapter implements CredentialTokenPr
* @param context The context object for the turn.
* @param connectionName The name of the auth connection to use.
* @param oAuthAppCredentials AppCredentials for OAuth.
* @param userId The user id that will be associated with the token.
* @param finalRedirect The final URL that the OAuth flow will redirect to.
*/
public async getSignInLink(context: TurnContext, connectionName: string): Promise<string>;
public async getSignInLink(context: TurnContext, connectionName: string, oAuthAppCredentials?: AppCredentials): Promise<string>;
public async getSignInLink(context: TurnContext, connectionName: string, oAuthAppCredentials?: AppCredentials): Promise<string> {
public async getSignInLink(context: TurnContext, connectionName: string, oAuthAppCredentials?: AppCredentials, userId?: string, finalRedirect?: string): Promise<string> {
if (userId && userId != context.activity.from.id) {
throw new ReferenceError(`cannot retrieve OAuth signin link for a user that's different from the conversation`);
}

this.checkEmulatingOAuthCards(context);
const conversation: Partial<ConversationReference> = TurnContext.getConversationReference(context.activity);
const url: string = this.oauthApiUrl(context);
Expand All @@ -597,7 +601,7 @@ export class BotFrameworkAdapter extends BotAdapter implements CredentialTokenPr
};

const finalState: string = Buffer.from(JSON.stringify(state)).toString('base64');
return (await client.botSignIn.getSignInUrl(finalState, { channelId: context.activity.channelId }))._response.bodyAsText;
return (await client.botSignIn.getSignInUrl(finalState, { channelId: context.activity.channelId, finalRedirect }))._response.bodyAsText;
}

/**
Expand Down
92 changes: 92 additions & 0 deletions libraries/botbuilder/tests/botFrameworkAdapter.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1024,6 +1024,98 @@ describe(`BotFrameworkAdapter`, function () {
assert(false, `should have thrown an error message`);
});

describe('getSignInLink()', () => {
it(`should throw if userName != from.id`, async () => {
const adapter = new BotFrameworkAdapter();
const context = new TurnContext(adapter, incomingMessage);
try {
const response = await adapter.getSignInLink(context, 'aConnectionName', new MicrosoftAppCredentials('abc', 'abc'), 'invalidId');
} catch (err) {
assert(err.message === `cannot retrieve OAuth signin link for a user that's different from the conversation`);
return;
}
assert(false, `should have thrown an error message`);
});
it(`should return return a sign-in URL with context and connectionName`, async () => {
const argsPassedToMockClient = [];
class MockTokenApiClient {
constructor() {
this.botSignIn = {
getSignInUrl: async (...args) => {
argsPassedToMockClient.push({getSignInUrl: args});
return {
_response: {status: 200, bodyAsText: 'http://mockedurl.com' }
}
}
};
this.credentials = new MicrosoftAppCredentials('abc', 'abc');
}

}
const {TokenApiClient} = connector;
connector.TokenApiClient = MockTokenApiClient;

const adapter = new BotFrameworkAdapter();
const context = new TurnContext(adapter, incomingMessage);
const response = await adapter.getSignInLink(context, 'aConnectionName');
assert(response, 'http://mockedurl.com');

connector.TokenApiClient = TokenApiClient; // restore
});
it(`should return return a sign-in URL with context connectionName, oauthAppCredentials`, async () => {
const argsPassedToMockClient = [];
class MockTokenApiClient {
constructor() {
this.botSignIn = {
getSignInUrl: async (...args) => {
argsPassedToMockClient.push({getSignInUrl: args});
return {
_response: {status: 200, bodyAsText: 'http://mockedurl.com' }
}
}
};
this.credentials = new MicrosoftAppCredentials('abc', 'abc');
}

}
const {TokenApiClient} = connector;
connector.TokenApiClient = MockTokenApiClient;

const adapter = new BotFrameworkAdapter();
const context = new TurnContext(adapter, incomingMessage);
const response = await adapter.getSignInLink(context, 'aConnectionName', new MicrosoftAppCredentials('abc', 'abc'));
assert(response, 'http://mockedurl.com');

connector.TokenApiClient = TokenApiClient; // restore
});
it(`should return return a sign-in URL with context connectionName, oauthAppCredentials, userId, finalRedirect`, async () => {
const argsPassedToMockClient = [];
class MockTokenApiClient {
constructor() {
this.botSignIn = {
getSignInUrl: async (...args) => {
argsPassedToMockClient.push({getSignInUrl: args});
return {
_response: {status: 200, bodyAsText: 'http://mockedurl.com' }
}
}
};
this.credentials = new MicrosoftAppCredentials('abc', 'abc');
}

}
const {TokenApiClient} = connector;
connector.TokenApiClient = MockTokenApiClient;

const adapter = new BotFrameworkAdapter();
const context = new TurnContext(adapter, incomingMessage);
const response = await adapter.getSignInLink(context, 'aConnectionName', new MicrosoftAppCredentials('abc', 'abc'), incomingMessage.from.id, 'http://finalredirect.com');
assert(response, 'http://mockedurl.com');

connector.TokenApiClient = TokenApiClient; // restore
});
});

describe('getTokenStatus()', () => {
xit(`should return the status of every connection the user has`, async () => {
const adapter = new AdapterUnderTest();
Expand Down