@strav/social 0.4.28 → 0.4.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +4 -4
- package/src/index.ts +1 -0
- package/src/providers/line_provider.ts +73 -0
- package/src/social_manager.ts +3 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@strav/social",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.29",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "OAuth social authentication for the Strav framework",
|
|
6
6
|
"license": "MIT",
|
|
@@ -16,9 +16,9 @@
|
|
|
16
16
|
"CHANGELOG.md"
|
|
17
17
|
],
|
|
18
18
|
"peerDependencies": {
|
|
19
|
-
"@strav/kernel": "0.4.
|
|
20
|
-
"@strav/http": "0.4.
|
|
21
|
-
"@strav/database": "0.4.
|
|
19
|
+
"@strav/kernel": "0.4.29",
|
|
20
|
+
"@strav/http": "0.4.29",
|
|
21
|
+
"@strav/database": "0.4.29"
|
|
22
22
|
},
|
|
23
23
|
"scripts": {
|
|
24
24
|
"test": "bun test tests/",
|
package/src/index.ts
CHANGED
|
@@ -10,5 +10,6 @@ export { GitHubProvider } from './providers/github_provider.ts'
|
|
|
10
10
|
export { DiscordProvider } from './providers/discord_provider.ts'
|
|
11
11
|
export { FacebookProvider } from './providers/facebook_provider.ts'
|
|
12
12
|
export { LinkedInProvider } from './providers/linkedin_provider.ts'
|
|
13
|
+
export { LineProvider } from './providers/line_provider.ts'
|
|
13
14
|
export type { SocialUser, SocialConfig, ProviderConfig, TokenResponse } from './types.ts'
|
|
14
15
|
export type { SocialAccountData } from './social_account.ts'
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { ExternalServiceError, scrubProviderError } from '@strav/kernel'
|
|
2
|
+
import { AbstractProvider } from '../abstract_provider.ts'
|
|
3
|
+
import type { SocialUser } from '../types.ts'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* LINE Login OAuth 2.1 provider.
|
|
7
|
+
*
|
|
8
|
+
* Distinct from the LINE Messaging API (handled by @strav/line) — this is
|
|
9
|
+
* the user-facing OAuth flow that lets a website log a user in with their
|
|
10
|
+
* LINE account.
|
|
11
|
+
*
|
|
12
|
+
* Scope notes:
|
|
13
|
+
* - `profile` (default) returns userId, displayName, pictureUrl.
|
|
14
|
+
* - `openid` (default) returns an ID token alongside the access token.
|
|
15
|
+
* - `email` is optional and requires the "Email permission" to be
|
|
16
|
+
* approved on the LINE Login channel — uncommon for new apps. The
|
|
17
|
+
* SocialUser.email will be null when this scope is not granted.
|
|
18
|
+
*
|
|
19
|
+
* @see https://developers.line.biz/en/docs/line-login/integrate-line-login/
|
|
20
|
+
*/
|
|
21
|
+
export class LineProvider extends AbstractProvider {
|
|
22
|
+
readonly name = 'LINE'
|
|
23
|
+
|
|
24
|
+
protected getDefaultScopes(): string[] {
|
|
25
|
+
return ['profile', 'openid']
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** LINE expects client_secret in the body, not as HTTP Basic. */
|
|
29
|
+
protected override defaultTokenEndpointAuthMethod(): 'basic' | 'post' {
|
|
30
|
+
return 'post'
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
protected getAuthUrl(): string {
|
|
34
|
+
return 'https://access.line.me/oauth2/v2.1/authorize'
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
protected getTokenUrl(): string {
|
|
38
|
+
return 'https://api.line.me/oauth2/v2.1/token'
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
protected async getUserByToken(token: string): Promise<Record<string, unknown>> {
|
|
42
|
+
const response = await fetch('https://api.line.me/v2/profile', {
|
|
43
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
if (!response.ok) {
|
|
47
|
+
throw new ExternalServiceError(
|
|
48
|
+
'LINE',
|
|
49
|
+
response.status,
|
|
50
|
+
scrubProviderError(await response.text())
|
|
51
|
+
)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return (await response.json()) as Record<string, unknown>
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
protected mapUserToObject(data: Record<string, unknown>): SocialUser {
|
|
58
|
+
return {
|
|
59
|
+
id: data.userId as string,
|
|
60
|
+
name: (data.displayName as string) ?? null,
|
|
61
|
+
email: (data.email as string) ?? null,
|
|
62
|
+
// LINE does not surface a "verified" flag on email; treat presence as verified.
|
|
63
|
+
emailVerified: typeof data.email === 'string',
|
|
64
|
+
avatar: (data.pictureUrl as string) ?? null,
|
|
65
|
+
nickname: null,
|
|
66
|
+
token: '',
|
|
67
|
+
refreshToken: null,
|
|
68
|
+
expiresIn: null,
|
|
69
|
+
approvedScopes: [],
|
|
70
|
+
raw: data,
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
package/src/social_manager.ts
CHANGED
|
@@ -7,6 +7,7 @@ import { GitHubProvider } from './providers/github_provider.ts'
|
|
|
7
7
|
import { DiscordProvider } from './providers/discord_provider.ts'
|
|
8
8
|
import { FacebookProvider } from './providers/facebook_provider.ts'
|
|
9
9
|
import { LinkedInProvider } from './providers/linkedin_provider.ts'
|
|
10
|
+
import { LineProvider } from './providers/line_provider.ts'
|
|
10
11
|
|
|
11
12
|
@inject
|
|
12
13
|
export default class SocialManager {
|
|
@@ -76,6 +77,8 @@ export default class SocialManager {
|
|
|
76
77
|
return new FacebookProvider(providerConfig)
|
|
77
78
|
case 'linkedin':
|
|
78
79
|
return new LinkedInProvider(providerConfig)
|
|
80
|
+
case 'line':
|
|
81
|
+
return new LineProvider(providerConfig)
|
|
79
82
|
default:
|
|
80
83
|
throw new ConfigurationError(
|
|
81
84
|
`Unknown social driver "${driverName}". Register it with SocialManager.extend().`
|