@moteurio/plugin-auth-github 2026.10.23-2 → 2026.10.28

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.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,kBAAkB,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AAC7G,OAAO,EAMH,KAAK,iBAAiB,IAAI,aAAa,EAC1C,MAAM,sBAAsB,CAAC;AAM9B,eAAO,MAAM,QAAQ,EAAE,cAOtB,CAAC;AAEF,wBAAgB,IAAI,CAAC,IAAI,EAAE,aAAa,GAAG,IAAI,CAAG;AAiGlD,wBAAgB,SAAS,CAAC,GAAG,EAAE,kBAAkB,GAAG,uBAAuB,CAM1E;AAED,wBAAgB,gBAAgB;;;;;;IAU/B;;;;;;;AAED,wBAA+D"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACR,cAAc,EACd,kBAAkB,EAClB,uBAAuB,EAC1B,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAOH,KAAK,iBAAiB,IAAI,aAAa,EAC1C,MAAM,sBAAsB,CAAC;AAM9B,eAAO,MAAM,QAAQ,EAAE,cAYtB,CAAC;AAEF,wBAAgB,IAAI,CAAC,IAAI,EAAE,aAAa,GAAG,IAAI,CAAG;AAsHlD,wBAAgB,SAAS,CAAC,GAAG,EAAE,kBAAkB,GAAG,uBAAuB,CAM1E;AAED,wBAAgB,gBAAgB;;;;;;IAU/B;;;;;;;AAED,wBAA+D"}
package/dist/index.js CHANGED
@@ -3,8 +3,8 @@
3
3
  */
4
4
  import { Router } from 'express';
5
5
  import axios from 'axios';
6
- import { beginOAuth, completeOAuth, oauthConfig, redirectAfterLogin, redirectLoginFailed } from '@moteurio/plugin-sdk';
7
- import { loginWithProvider } from '@moteurio/core/auth.js';
6
+ import { beginOAuth, completeOAuth, oauthChallenge, oauthConfig, redirectProviderSignIn, redirectLoginFailed } from '@moteurio/plugin-sdk';
7
+ import { startProviderSignIn } from '@moteurio/core/host.js';
8
8
  const NOT_OFFERED = { error: 'GitHub sign-in is not available on this server.' };
9
9
  export const manifest = {
10
10
  id: 'auth-github',
@@ -12,7 +12,12 @@ export const manifest = {
12
12
  description: 'Sign in with GitHub',
13
13
  source: 'opensource',
14
14
  kind: 'optional',
15
- scope: 'global'
15
+ scope: 'global',
16
+ categories: ['auth'],
17
+ contributes: {
18
+ api: { mounts: ['/auth'], openApi: true },
19
+ auth: { providers: ['github'] }
20
+ }
16
21
  };
17
22
  export function init(_ctx) { }
18
23
  function createGitHubRouter(ctx) {
@@ -23,11 +28,14 @@ function createGitHubRouter(ctx) {
23
28
  res.status(404).json(NOT_OFFERED);
24
29
  return;
25
30
  }
31
+ const state = beginOAuth(req, res, 'github');
26
32
  const params = new URLSearchParams({
27
33
  client_id: config.clientId,
28
34
  redirect_uri: config.redirectUri,
29
35
  scope: 'read:user user:email',
30
- state: beginOAuth(req, res, 'github')
36
+ state,
37
+ code_challenge: oauthChallenge(state),
38
+ code_challenge_method: 'S256'
31
39
  });
32
40
  res.redirect(`https://github.com/login/oauth/authorize?${params.toString()}`);
33
41
  });
@@ -48,6 +56,7 @@ function createGitHubRouter(ctx) {
48
56
  client_id: config.clientId,
49
57
  client_secret: config.clientSecret,
50
58
  code,
59
+ code_verifier: started.verifier,
51
60
  redirect_uri: config.redirectUri
52
61
  }, { headers: { Accept: 'application/json' } });
53
62
  const accessToken = tokenRes.data.access_token;
@@ -58,12 +67,18 @@ function createGitHubRouter(ctx) {
58
67
  axios.get('https://api.github.com/user', { headers }),
59
68
  axios.get('https://api.github.com/user/emails', { headers })
60
69
  ]);
61
- const email = emailsRes.data.find((e) => e.primary && e.verified)?.email;
62
- if (!email)
63
- return redirectLoginFailed(res, 'email');
70
+ const email = emailsRes.data.find((e) => e.primary === true && e.verified === true && typeof e.email === 'string')?.email;
64
71
  const profile = userRes.data;
65
- const { token } = await loginWithProvider({ auth: { githubId: profile.id }, email, name: profile.name || profile.login }, ctx.authCallbacks?.runOnboardingForNewUser);
66
- redirectAfterLogin(res, token, started.next);
72
+ if (!(typeof profile.id === 'number' && Number.isFinite(profile.id)))
73
+ return redirectLoginFailed(res, 'failed');
74
+ const suggestedEmail = emailsRes.data.find((item) => item.primary === true && typeof item.email === 'string')?.email;
75
+ const result = await startProviderSignIn({
76
+ auth: { githubId: profile.id },
77
+ email: email ?? '',
78
+ suggestedEmail,
79
+ name: profile.name || profile.login
80
+ }, ctx.authCallbacks?.runOnboardingForNewUser, { link: started.link });
81
+ redirectProviderSignIn(req, res, result, started.next);
67
82
  }
68
83
  catch (err) {
69
84
  if (err instanceof Error && err.message === 'User is not active') {
@@ -81,7 +96,9 @@ const openapi = {
81
96
  summary: 'Redirect to GitHub login',
82
97
  tags: ['Auth'],
83
98
  description: "Redirects the user to GitHub's OAuth login screen. `next` (a path in the app) is where they land after signing in.",
84
- parameters: [{ name: 'next', in: 'query', required: false, schema: { type: 'string' } }],
99
+ parameters: [
100
+ { name: 'next', in: 'query', required: false, schema: { type: 'string' } }
101
+ ],
85
102
  responses: { '302': { description: 'Redirect to GitHub OAuth screen' } }
86
103
  }
87
104
  },
@@ -89,12 +106,16 @@ const openapi = {
89
106
  get: {
90
107
  summary: 'GitHub OAuth callback',
91
108
  tags: ['Auth'],
92
- description: 'Checks `state` against the browser that started the sign-in, creates or reuses the account with the verified primary email, then redirects to `AUTH_REDIRECT_AFTER_LOGIN` with `#token=…&next=…`, or `#error=state|email|inactive|failed`.',
109
+ description: 'Checks `state` against the browser that started the sign-in, matches the provider identity or starts browser-bound verification/linking, then redirects to `AUTH_REDIRECT_AFTER_LOGIN` with `#token=…&next=…`, or `#error=state|email|inactive|failed`.',
93
110
  parameters: [
94
111
  { name: 'code', in: 'query', required: true, schema: { type: 'string' } },
95
112
  { name: 'state', in: 'query', required: true, schema: { type: 'string' } }
96
113
  ],
97
- responses: { '302': { description: 'Redirect to the app with a token or an error in the fragment' } }
114
+ responses: {
115
+ '302': {
116
+ description: 'Redirect to the app with a token or an error in the fragment'
117
+ }
118
+ }
98
119
  }
99
120
  }
100
121
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moteurio/plugin-auth-github",
3
- "version": "2026.10.23-2",
3
+ "version": "2026.10.28",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -11,14 +11,19 @@
11
11
  "dist"
12
12
  ],
13
13
  "dependencies": {
14
- "@moteurio/core": "^2026.10.23-2",
15
- "@moteurio/plugin-sdk": "^2026.10.23-2",
16
- "@moteurio/types": "^2026.10.23-2",
17
14
  "axios": "^1.13.6",
18
15
  "express": "^4.19.2",
19
16
  "openapi-types": "^12.1.3"
20
17
  },
18
+ "peerDependencies": {
19
+ "@moteurio/core": "^2026.10.28",
20
+ "@moteurio/plugin-sdk": "^2026.10.28",
21
+ "@moteurio/types": "^2026.10.28"
22
+ },
21
23
  "devDependencies": {
24
+ "@moteurio/core": "^2026.10.28",
25
+ "@moteurio/plugin-sdk": "^2026.10.28",
26
+ "@moteurio/types": "^2026.10.28",
22
27
  "@types/express": "^5.0.3"
23
28
  },
24
29
  "license": "MIT",