@atproto/pds 0.4.199 → 0.4.201

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.
Files changed (65) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/dist/api/com/atproto/server/createSession.d.ts.map +1 -1
  3. package/dist/api/com/atproto/server/createSession.js +2 -2
  4. package/dist/api/com/atproto/server/createSession.js.map +1 -1
  5. package/dist/api/com/atproto/server/getSession.js +2 -2
  6. package/dist/api/com/atproto/server/getSession.js.map +1 -1
  7. package/dist/api/com/atproto/server/refreshSession.d.ts.map +1 -1
  8. package/dist/api/com/atproto/server/refreshSession.js +4 -2
  9. package/dist/api/com/atproto/server/refreshSession.js.map +1 -1
  10. package/dist/lexicon/lexicons.d.ts +144 -54
  11. package/dist/lexicon/lexicons.d.ts.map +1 -1
  12. package/dist/lexicon/lexicons.js +94 -26
  13. package/dist/lexicon/lexicons.js.map +1 -1
  14. package/dist/lexicon/types/app/bsky/contact/dismissMatch.d.ts +1 -1
  15. package/dist/lexicon/types/app/bsky/contact/dismissMatch.d.ts.map +1 -1
  16. package/dist/lexicon/types/app/bsky/contact/dismissMatch.js.map +1 -1
  17. package/dist/lexicon/types/app/bsky/contact/getMatches.d.ts +1 -1
  18. package/dist/lexicon/types/app/bsky/contact/getMatches.d.ts.map +1 -1
  19. package/dist/lexicon/types/app/bsky/contact/getMatches.js.map +1 -1
  20. package/dist/lexicon/types/app/bsky/contact/getSyncStatus.d.ts +1 -1
  21. package/dist/lexicon/types/app/bsky/contact/getSyncStatus.d.ts.map +1 -1
  22. package/dist/lexicon/types/app/bsky/contact/getSyncStatus.js.map +1 -1
  23. package/dist/lexicon/types/app/bsky/contact/importContacts.d.ts +1 -1
  24. package/dist/lexicon/types/app/bsky/contact/importContacts.d.ts.map +1 -1
  25. package/dist/lexicon/types/app/bsky/contact/importContacts.js.map +1 -1
  26. package/dist/lexicon/types/app/bsky/contact/removeData.d.ts +1 -1
  27. package/dist/lexicon/types/app/bsky/contact/removeData.d.ts.map +1 -1
  28. package/dist/lexicon/types/app/bsky/contact/removeData.js.map +1 -1
  29. package/dist/lexicon/types/app/bsky/contact/startPhoneVerification.d.ts +1 -1
  30. package/dist/lexicon/types/app/bsky/contact/startPhoneVerification.d.ts.map +1 -1
  31. package/dist/lexicon/types/app/bsky/contact/startPhoneVerification.js.map +1 -1
  32. package/dist/lexicon/types/app/bsky/contact/verifyPhone.d.ts +1 -1
  33. package/dist/lexicon/types/app/bsky/contact/verifyPhone.d.ts.map +1 -1
  34. package/dist/lexicon/types/app/bsky/contact/verifyPhone.js.map +1 -1
  35. package/dist/lexicon/types/app/bsky/notification/listNotifications.d.ts +1 -1
  36. package/dist/lexicon/types/app/bsky/notification/listNotifications.d.ts.map +1 -1
  37. package/dist/lexicon/types/app/bsky/notification/listNotifications.js.map +1 -1
  38. package/dist/lexicon/types/com/atproto/server/deleteSession.d.ts +1 -0
  39. package/dist/lexicon/types/com/atproto/server/deleteSession.d.ts.map +1 -1
  40. package/dist/lexicon/types/com/atproto/server/deleteSession.js.map +1 -1
  41. package/dist/lexicon/types/com/atproto/server/getSession.d.ts +3 -3
  42. package/dist/lexicon/types/com/atproto/server/getSession.d.ts.map +1 -1
  43. package/dist/lexicon/types/com/atproto/server/getSession.js.map +1 -1
  44. package/dist/lexicon/types/com/atproto/server/refreshSession.d.ts +4 -1
  45. package/dist/lexicon/types/com/atproto/server/refreshSession.d.ts.map +1 -1
  46. package/dist/lexicon/types/com/atproto/server/refreshSession.js.map +1 -1
  47. package/package.json +15 -15
  48. package/src/api/com/atproto/server/createSession.ts +3 -2
  49. package/src/api/com/atproto/server/getSession.ts +2 -2
  50. package/src/api/com/atproto/server/refreshSession.ts +5 -2
  51. package/src/lexicon/lexicons.ts +95 -26
  52. package/src/lexicon/types/app/bsky/contact/dismissMatch.ts +1 -1
  53. package/src/lexicon/types/app/bsky/contact/getMatches.ts +1 -1
  54. package/src/lexicon/types/app/bsky/contact/getSyncStatus.ts +1 -1
  55. package/src/lexicon/types/app/bsky/contact/importContacts.ts +6 -1
  56. package/src/lexicon/types/app/bsky/contact/removeData.ts +1 -1
  57. package/src/lexicon/types/app/bsky/contact/startPhoneVerification.ts +1 -1
  58. package/src/lexicon/types/app/bsky/contact/verifyPhone.ts +6 -1
  59. package/src/lexicon/types/app/bsky/notification/listNotifications.ts +1 -0
  60. package/src/lexicon/types/com/atproto/server/deleteSession.ts +1 -0
  61. package/src/lexicon/types/com/atproto/server/getSession.ts +1 -1
  62. package/src/lexicon/types/com/atproto/server/refreshSession.ts +4 -1
  63. package/tests/_puppeteer.ts +87 -0
  64. package/tests/oauth.test.ts +54 -94
  65. package/tsconfig.tests.tsbuildinfo +0 -1
@@ -1,4 +1,3 @@
1
- import assert from 'node:assert'
2
1
  import { once } from 'node:events'
3
2
  import {
4
3
  IncomingMessage,
@@ -7,93 +6,25 @@ import {
7
6
  createServer,
8
7
  } from 'node:http'
9
8
  import { AddressInfo } from 'node:net'
10
- import { type Browser, type Page, launch } from 'puppeteer'
9
+ import { type Browser, launch } from 'puppeteer'
11
10
  import { TestNetworkNoAppView } from '@atproto/dev-env'
12
- // @ts-expect-error (json file)
13
11
  import files from '@atproto/oauth-client-browser-example' with { type: 'json' }
14
-
15
- class PageHelper implements AsyncDisposable {
16
- constructor(protected readonly page: Page) {}
17
-
18
- async goto(url: string) {
19
- await this.page.goto(url)
20
- }
21
-
22
- async waitForNetworkIdle() {
23
- await this.page.waitForNetworkIdle()
24
- }
25
-
26
- async navigationAction(run: () => Promise<unknown>): Promise<void> {
27
- const promise = this.page.waitForNavigation()
28
- await run()
29
- await promise
30
- await this.waitForNetworkIdle()
31
- }
32
-
33
- async checkTitle(expected: string) {
34
- await this.waitForNetworkIdle()
35
- await expect(this.page.title()).resolves.toBe(expected)
36
- }
37
-
38
- async clickOn(selector: string) {
39
- const elementHandle = await this.getVisibleElement(selector)
40
- await elementHandle.click()
41
- return elementHandle
42
- }
43
-
44
- async clickOnButton(text: string) {
45
- return this.clickOn(`button::-p-text(${text})`)
46
- }
47
-
48
- async typeIn(selector: string, text: string) {
49
- const elementHandle = await this.getVisibleElement(selector)
50
- elementHandle.focus()
51
- await elementHandle.type(text)
52
- return elementHandle
53
- }
54
-
55
- async typeInInput(name: string, text: string) {
56
- return this.typeIn(`input[name="${name}"]`, text)
57
- }
58
-
59
- async ensureTextVisibility(text: string, tag = 'p') {
60
- await this.page.waitForSelector(`${tag}::-p-text(${text})`)
61
- }
62
-
63
- protected async getVisibleElement(selector: string) {
64
- const elementHandle = await this.page.waitForSelector(selector)
65
-
66
- expect(elementHandle).not.toBeNull()
67
- assert(elementHandle)
68
-
69
- await expect(elementHandle.isVisible()).resolves.toBe(true)
70
-
71
- return elementHandle
72
- }
73
-
74
- async [Symbol.asyncDispose]() {
75
- return this.page.close()
76
- }
77
-
78
- static async from(browser: Browser) {
79
- const page = await browser.newPage()
80
- return new PageHelper(page)
81
- }
82
- }
12
+ import { PageHelper } from './_puppeteer.js'
83
13
 
84
14
  describe('oauth', () => {
85
15
  let browser: Browser
86
16
  let network: TestNetworkNoAppView
87
- let client: Server
17
+ let server: Server
88
18
 
89
19
  let appUrl: string
90
20
 
21
+ // @NOTE We are using another language than "en" as default language to
22
+ // test the language negotiation.
23
+ const languages = ['fr-BE', 'fr', 'en-US', 'en']
24
+
91
25
  beforeAll(async () => {
92
26
  browser = await launch({
93
- browser: 'chrome',
94
- // @NOTE We are using another language than "en" as default language to
95
- // test the language negotiation.
96
- args: ['--accept-lang=fr-BE,en-GB,en'],
27
+ browser: 'chrome', // "firefox"
97
28
 
98
29
  // For debugging:
99
30
  // headless: false,
@@ -113,11 +44,11 @@ describe('oauth', () => {
113
44
  password: 'alice-pass',
114
45
  })
115
46
 
116
- client = createServer(clientHandler)
117
- client.listen(0)
118
- await once(client, 'listening')
47
+ server = createServer(clientHandler)
48
+ server.listen(0)
49
+ await once(server, 'listening')
119
50
 
120
- const { port } = client.address() as AddressInfo
51
+ const { port } = server.address() as AddressInfo
121
52
 
122
53
  appUrl = `http://127.0.0.1:${port}?${new URLSearchParams({
123
54
  plc_directory_url: network.plc.url,
@@ -129,27 +60,24 @@ describe('oauth', () => {
129
60
  })
130
61
 
131
62
  afterAll(async () => {
132
- await client?.close()
63
+ await server?.close()
133
64
  await network?.close()
134
65
  await browser?.close()
135
66
  })
136
67
 
137
- it('Allows to sign-up trough OAuth', async () => {
138
- const page = await PageHelper.from(browser)
68
+ // This uses prompt=create under the hood:
69
+ it('Allows to sign-up through OAuth', async () => {
70
+ const page = await PageHelper.from(browser, { languages })
139
71
 
140
72
  await page.goto(appUrl)
141
73
 
142
74
  await page.checkTitle('OAuth Client Example')
143
75
 
144
76
  await page.navigationAction(async () => {
145
- await page.clickOnButton(
146
- `Login or signup with ${new URL(network.pds.url).host}`,
147
- )
77
+ await page.clickOnButton(`Sign up with ${new URL(network.pds.url).host}`)
148
78
  })
149
79
 
150
- await page.checkTitle('Authentification')
151
-
152
- await page.clickOnButton('Créer un nouveau compte')
80
+ await page.checkTitle('Créer un compte')
153
81
 
154
82
  await page.typeInInput('handle', 'bob')
155
83
 
@@ -186,6 +114,38 @@ describe('oauth', () => {
186
114
  await page[Symbol.asyncDispose]()
187
115
  })
188
116
 
117
+ it('Allows login or signup through OAuth via a choice', async () => {
118
+ const page = await PageHelper.from(browser, { languages })
119
+
120
+ await page.goto(appUrl)
121
+
122
+ await page.checkTitle('OAuth Client Example')
123
+
124
+ await page.navigationAction(async () => {
125
+ await page.clickOnButton(`Login with ${new URL(network.pds.url).host}`)
126
+ })
127
+
128
+ await page.checkTitle('Authentification')
129
+
130
+ await page.ensureTextVisibility('Annuler', 'button')
131
+ await page.ensureTextVisibility('Se connecter', 'button')
132
+ await page.ensureTextVisibility('Créer un nouveau compte', 'button')
133
+
134
+ // Cancel the OAuth flow:
135
+ await page.navigationAction(async () => {
136
+ await page.clickOnButton('Annuler')
137
+ })
138
+
139
+ await page.checkTitle('OAuth Client Example')
140
+
141
+ await page.ensureTextVisibility('Login with the Atmosphere', 'h2')
142
+
143
+ await page.waitForNetworkIdle()
144
+
145
+ // TODO: Find out why we can't use "using" here
146
+ await page[Symbol.asyncDispose]()
147
+ })
148
+
189
149
  it('allows resetting the password', async () => {
190
150
  const sendTemplateMock = jest
191
151
  .spyOn(network.pds.ctx.mailer, 'sendResetPassword')
@@ -193,7 +153,7 @@ describe('oauth', () => {
193
153
  // noop
194
154
  })
195
155
 
196
- const page = await PageHelper.from(browser)
156
+ const page = await PageHelper.from(browser, { languages })
197
157
 
198
158
  await page.goto(appUrl)
199
159
 
@@ -243,8 +203,8 @@ describe('oauth', () => {
243
203
  sendTemplateMock.mockRestore()
244
204
  })
245
205
 
246
- it('Allows to sign-in trough OAuth', async () => {
247
- const page = await PageHelper.from(browser)
206
+ it('Allows to sign-in through OAuth', async () => {
207
+ const page = await PageHelper.from(browser, { languages })
248
208
 
249
209
  await page.goto(appUrl)
250
210
 
@@ -290,7 +250,7 @@ describe('oauth', () => {
290
250
  })
291
251
 
292
252
  it('remembers the session', async () => {
293
- const page = await PageHelper.from(browser)
253
+ const page = await PageHelper.from(browser, { languages })
294
254
 
295
255
  await page.goto(appUrl)
296
256
 
@@ -1 +0,0 @@
1
- {"root":["./tests/_util.ts","./tests/account-deactivation.test.ts","./tests/account-deletion.test.ts","./tests/account-migration.test.ts","./tests/account.test.ts","./tests/app-passwords.test.ts","./tests/auth.test.ts","./tests/blob-deletes.test.ts","./tests/create-post.test.ts","./tests/crud.test.ts","./tests/db.test.ts","./tests/email-confirmation.test.ts","./tests/entryway.test.ts","./tests/file-uploads.test.ts","./tests/handle-validation.test.ts","./tests/handles.test.ts","./tests/invite-codes.test.ts","./tests/invites-admin.test.ts","./tests/moderation.test.ts","./tests/moderator-auth.test.ts","./tests/oauth.test.ts","./tests/plc-operations.test.ts","./tests/preferences.test.ts","./tests/races.test.ts","./tests/rate-limits.test.ts","./tests/recovery.test.ts","./tests/sequencer.test.ts","./tests/server.test.ts","./tests/takedown-appeal.test.ts","./tests/proxied/admin.test.ts","./tests/proxied/feedgen.test.ts","./tests/proxied/notif.test.ts","./tests/proxied/procedures.test.ts","./tests/proxied/proxy-catchall.test.ts","./tests/proxied/proxy-header.test.ts","./tests/proxied/read-after-write.test.ts","./tests/proxied/views.test.ts","./tests/seeds/basic.ts","./tests/seeds/follows.ts","./tests/seeds/likes.ts","./tests/seeds/reposts.ts","./tests/seeds/thread.ts","./tests/seeds/users-bulk.ts","./tests/seeds/users.ts","./tests/sync/invertible-ops.test.ts","./tests/sync/list.test.ts","./tests/sync/subscribe-repos.test.ts","./tests/sync/sync.test.ts"],"version":"5.8.3"}