Skip to content

Commit 5bd9a49

Browse files
authored
Support Channel access token v2.1 (#223)
1 parent d64efa4 commit 5bd9a49

File tree

4 files changed

+129
-22
lines changed

4 files changed

+129
-22
lines changed

docs/api-reference/oauth.md

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,19 @@ corresponding to [messaging APIs](https://developers.line.biz/en/reference/messa
99
class OAuth {
1010
constructor() {}
1111

12-
issueAccessToken(client_id: string, client_secret: string): Promise<{
13-
access_token: string;
14-
expires_in: number;
15-
token_type: "Bearer";
16-
}>
12+
issueAccessToken(client_id: string, client_secret: string): Promise<Types.ChannelAccessToken>
1713
revokeAccessToken(access_token: string): Promise<{}>
14+
issueChannelAccessTokenV2_1(
15+
client_assertion: string,
16+
): Promise<Types.ChannelAccessToken>
17+
getIssuedChannelAccessTokenV2_1(
18+
client_assertion: string,
19+
): Promise<{ access_tokens: string[] }>
20+
revokeChannelAccessTokenV2_1(
21+
client_id: string,
22+
client_secret: string,
23+
access_token: string,
24+
): Promise<{}>
1825
}
1926
```
2027

@@ -51,7 +58,7 @@ in [the Client guide](../guide/client.md).
5158

5259
### OAuth
5360

54-
#### `issueAccessToken(client_id: string, client_secret: string): Promise<{ access_token: string; expires_in: number; token_type: "Bearer"; }>`
61+
#### `issueAccessToken(client_id: string, client_secret: string): Promise<Types.ChannelAccessToken>`
5562

5663
It corresponds to the [Issue channel access token](https://developers.line.biz/en/reference/messaging-api/#issue-channel-access-token) API.
5764

@@ -67,4 +74,17 @@ It corresponds to the [Revoke channel access token](https://developers.line.biz/
6774

6875
``` js
6976
await oauth.revokeAccessToken("access_token");
70-
```
77+
```
78+
79+
80+
#### issueChannelAccessTokenV2_1(client_assertion: string): Promise<Types.ChannelAccessToken>
81+
82+
It corresponds to the [Issue channel access token v2.1](https://developers.line.biz/en/reference/messaging-api/#issue-channel-access-token-v2-1) API.
83+
84+
#### getIssuedChannelAccessTokenV2_1(client_assertion: string): Promise<{ access_tokens: string[] }>
85+
86+
It corresponds to the [Get Issued channel access token v2.1](https://developers.line.biz/en/reference/messaging-api/#get-issued-channel-access-tokens-v2-1) API.
87+
88+
#### revokeChannelAccessTokenV2_1(client_id: string, client_secret: string, access_token: string): Promise<{}>
89+
90+
It corresponds to the [Revoke channel access token v2.1](https://developers.line.biz/en/reference/messaging-api/#revoke-channel-access-token-v2-1) API.

lib/client.ts

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -603,11 +603,7 @@ export class OAuth {
603603
public issueAccessToken(
604604
client_id: string,
605605
client_secret: string,
606-
): Promise<{
607-
access_token: string;
608-
expires_in: number;
609-
token_type: "Bearer";
610-
}> {
606+
): Promise<Types.ChannelAccessToken> {
611607
return this.http.postForm(`${OAUTH_BASE_PREFIX}/accessToken`, {
612608
grant_type: "client_credentials",
613609
client_id,
@@ -618,4 +614,37 @@ export class OAuth {
618614
public revokeAccessToken(access_token: string): Promise<{}> {
619615
return this.http.postForm(`${OAUTH_BASE_PREFIX}/revoke`, { access_token });
620616
}
617+
618+
public issueChannelAccessTokenV2_1(
619+
client_assertion: string,
620+
): Promise<Types.ChannelAccessToken> {
621+
return this.http.postForm(`${OAUTH_BASE_PREFIX}/v2.1/token`, {
622+
grant_type: "client_credentials",
623+
client_assertion_type:
624+
"urn:ietf:params:oauth:client-assertion-type:jwt-bearer",
625+
client_assertion,
626+
});
627+
}
628+
629+
public getIssuedChannelAccessTokenV2_1(
630+
client_assertion: string,
631+
): Promise<{ access_tokens: string[] }> {
632+
return this.http.get(`${OAUTH_BASE_PREFIX}/v2.1/tokens`, {
633+
client_assertion_type:
634+
"urn:ietf:params:oauth:client-assertion-type:jwt-bearer",
635+
client_assertion,
636+
});
637+
}
638+
639+
public revokeChannelAccessTokenV2_1(
640+
client_id: string,
641+
client_secret: string,
642+
access_token: string,
643+
): Promise<{}> {
644+
return this.http.postForm(`${OAUTH_BASE_PREFIX}/v2.1/revoke`, {
645+
client_id,
646+
client_secret,
647+
access_token,
648+
});
649+
}
621650
}

lib/types.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2426,6 +2426,12 @@ export type AudienceGroups = _AudienceGroup[];
24262426

24272427
export type AudienceGroupAuthorityLevel = "PUBLIC" | "PRIVATE";
24282428

2429+
export type ChannelAccessToken = {
2430+
access_token: string;
2431+
expires_in: number;
2432+
token_type: "Bearer";
2433+
};
2434+
24292435
/**
24302436
* Response body of get group summary.
24312437
*

test/client.spec.ts

Lines changed: 62 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -901,6 +901,12 @@ describe("oauth", () => {
901901
afterEach(() => nock.cleanAll());
902902
after(() => nock.enableNetConnect());
903903

904+
const accessTokenReply = {
905+
access_token: "access_token",
906+
expires_in: 2592000,
907+
token_type: "Bearer",
908+
};
909+
904910
const interceptionOption = {
905911
reqheaders: {
906912
"content-type": "application/x-www-form-urlencoded",
@@ -917,19 +923,11 @@ describe("oauth", () => {
917923
client_id,
918924
client_secret,
919925
})
920-
.reply(200, {
921-
access_token: "access_token",
922-
expires_in: 2592000,
923-
token_type: "Bearer",
924-
});
926+
.reply(200, accessTokenReply);
925927

926928
const res = await oauth.issueAccessToken(client_id, client_secret);
927929
equal(scope.isDone(), true);
928-
deepEqual(res, {
929-
access_token: "access_token",
930-
expires_in: 2592000,
931-
token_type: "Bearer",
932-
});
930+
deepEqual(res, accessTokenReply);
933931
});
934932

935933
it("revokeAccessToken", async () => {
@@ -942,4 +940,58 @@ describe("oauth", () => {
942940
equal(scope.isDone(), true);
943941
deepEqual(res, {});
944942
});
943+
944+
it("issueChannelAccessTokenV2_1", async () => {
945+
const client_assertion = "client_assertion";
946+
947+
const scope = nock(OAUTH_BASE_PREFIX, interceptionOption)
948+
.post("/v2.1/token", {
949+
grant_type: "client_credentials",
950+
client_assertion_type:
951+
"urn:ietf:params:oauth:client-assertion-type:jwt-bearer",
952+
client_assertion,
953+
})
954+
.reply(200, accessTokenReply);
955+
956+
const res = await oauth.issueChannelAccessTokenV2_1(client_assertion);
957+
equal(scope.isDone(), true);
958+
deepEqual(res, accessTokenReply);
959+
});
960+
961+
it("getIssuedChannelAccessTokenV2_1", async () => {
962+
const client_assertion = "client_assertion";
963+
const accessTokenReply = {
964+
access_tokens: ["test_access_tokens"],
965+
};
966+
967+
const scope = nock(OAUTH_BASE_PREFIX)
968+
.get("/v2.1/tokens")
969+
.query({
970+
client_assertion_type:
971+
"urn:ietf:params:oauth:client-assertion-type:jwt-bearer",
972+
client_assertion,
973+
})
974+
.reply(200, accessTokenReply);
975+
976+
const res = await oauth.getIssuedChannelAccessTokenV2_1(client_assertion);
977+
equal(scope.isDone(), true);
978+
deepEqual(res, accessTokenReply);
979+
});
980+
981+
it("revokeChannelAccessTokenV2_1", async () => {
982+
const client_id = "test_client_id",
983+
client_secret = "test_client_secret",
984+
access_token = "test_channel_access_token";
985+
const scope = nock(OAUTH_BASE_PREFIX, interceptionOption)
986+
.post("/v2.1/revoke", { client_id, client_secret, access_token })
987+
.reply(200, {});
988+
989+
const res = await oauth.revokeChannelAccessTokenV2_1(
990+
client_id,
991+
client_secret,
992+
access_token,
993+
);
994+
equal(scope.isDone(), true);
995+
deepEqual(res, {});
996+
});
945997
});

0 commit comments

Comments
 (0)