@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.
- package/CHANGELOG.md +25 -0
- package/dist/api/com/atproto/server/createSession.d.ts.map +1 -1
- package/dist/api/com/atproto/server/createSession.js +2 -2
- package/dist/api/com/atproto/server/createSession.js.map +1 -1
- package/dist/api/com/atproto/server/getSession.js +2 -2
- package/dist/api/com/atproto/server/getSession.js.map +1 -1
- package/dist/api/com/atproto/server/refreshSession.d.ts.map +1 -1
- package/dist/api/com/atproto/server/refreshSession.js +4 -2
- package/dist/api/com/atproto/server/refreshSession.js.map +1 -1
- package/dist/lexicon/lexicons.d.ts +144 -54
- package/dist/lexicon/lexicons.d.ts.map +1 -1
- package/dist/lexicon/lexicons.js +94 -26
- package/dist/lexicon/lexicons.js.map +1 -1
- package/dist/lexicon/types/app/bsky/contact/dismissMatch.d.ts +1 -1
- package/dist/lexicon/types/app/bsky/contact/dismissMatch.d.ts.map +1 -1
- package/dist/lexicon/types/app/bsky/contact/dismissMatch.js.map +1 -1
- package/dist/lexicon/types/app/bsky/contact/getMatches.d.ts +1 -1
- package/dist/lexicon/types/app/bsky/contact/getMatches.d.ts.map +1 -1
- package/dist/lexicon/types/app/bsky/contact/getMatches.js.map +1 -1
- package/dist/lexicon/types/app/bsky/contact/getSyncStatus.d.ts +1 -1
- package/dist/lexicon/types/app/bsky/contact/getSyncStatus.d.ts.map +1 -1
- package/dist/lexicon/types/app/bsky/contact/getSyncStatus.js.map +1 -1
- package/dist/lexicon/types/app/bsky/contact/importContacts.d.ts +1 -1
- package/dist/lexicon/types/app/bsky/contact/importContacts.d.ts.map +1 -1
- package/dist/lexicon/types/app/bsky/contact/importContacts.js.map +1 -1
- package/dist/lexicon/types/app/bsky/contact/removeData.d.ts +1 -1
- package/dist/lexicon/types/app/bsky/contact/removeData.d.ts.map +1 -1
- package/dist/lexicon/types/app/bsky/contact/removeData.js.map +1 -1
- package/dist/lexicon/types/app/bsky/contact/startPhoneVerification.d.ts +1 -1
- package/dist/lexicon/types/app/bsky/contact/startPhoneVerification.d.ts.map +1 -1
- package/dist/lexicon/types/app/bsky/contact/startPhoneVerification.js.map +1 -1
- package/dist/lexicon/types/app/bsky/contact/verifyPhone.d.ts +1 -1
- package/dist/lexicon/types/app/bsky/contact/verifyPhone.d.ts.map +1 -1
- package/dist/lexicon/types/app/bsky/contact/verifyPhone.js.map +1 -1
- package/dist/lexicon/types/app/bsky/notification/listNotifications.d.ts +1 -1
- package/dist/lexicon/types/app/bsky/notification/listNotifications.d.ts.map +1 -1
- package/dist/lexicon/types/app/bsky/notification/listNotifications.js.map +1 -1
- package/dist/lexicon/types/com/atproto/server/deleteSession.d.ts +1 -0
- package/dist/lexicon/types/com/atproto/server/deleteSession.d.ts.map +1 -1
- package/dist/lexicon/types/com/atproto/server/deleteSession.js.map +1 -1
- package/dist/lexicon/types/com/atproto/server/getSession.d.ts +3 -3
- package/dist/lexicon/types/com/atproto/server/getSession.d.ts.map +1 -1
- package/dist/lexicon/types/com/atproto/server/getSession.js.map +1 -1
- package/dist/lexicon/types/com/atproto/server/refreshSession.d.ts +4 -1
- package/dist/lexicon/types/com/atproto/server/refreshSession.d.ts.map +1 -1
- package/dist/lexicon/types/com/atproto/server/refreshSession.js.map +1 -1
- package/package.json +15 -15
- package/src/api/com/atproto/server/createSession.ts +3 -2
- package/src/api/com/atproto/server/getSession.ts +2 -2
- package/src/api/com/atproto/server/refreshSession.ts +5 -2
- package/src/lexicon/lexicons.ts +95 -26
- package/src/lexicon/types/app/bsky/contact/dismissMatch.ts +1 -1
- package/src/lexicon/types/app/bsky/contact/getMatches.ts +1 -1
- package/src/lexicon/types/app/bsky/contact/getSyncStatus.ts +1 -1
- package/src/lexicon/types/app/bsky/contact/importContacts.ts +6 -1
- package/src/lexicon/types/app/bsky/contact/removeData.ts +1 -1
- package/src/lexicon/types/app/bsky/contact/startPhoneVerification.ts +1 -1
- package/src/lexicon/types/app/bsky/contact/verifyPhone.ts +6 -1
- package/src/lexicon/types/app/bsky/notification/listNotifications.ts +1 -0
- package/src/lexicon/types/com/atproto/server/deleteSession.ts +1 -0
- package/src/lexicon/types/com/atproto/server/getSession.ts +1 -1
- package/src/lexicon/types/com/atproto/server/refreshSession.ts +4 -1
- package/tests/_puppeteer.ts +87 -0
- package/tests/oauth.test.ts +54 -94
- package/tsconfig.tests.tsbuildinfo +0 -1
package/tests/oauth.test.ts
CHANGED
|
@@ -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,
|
|
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
|
|
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
|
-
|
|
117
|
-
|
|
118
|
-
await once(
|
|
47
|
+
server = createServer(clientHandler)
|
|
48
|
+
server.listen(0)
|
|
49
|
+
await once(server, 'listening')
|
|
119
50
|
|
|
120
|
-
const { port } =
|
|
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
|
|
63
|
+
await server?.close()
|
|
133
64
|
await network?.close()
|
|
134
65
|
await browser?.close()
|
|
135
66
|
})
|
|
136
67
|
|
|
137
|
-
|
|
138
|
-
|
|
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('
|
|
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
|
|
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"}
|