@atproto/pds 0.5.11 → 0.5.14
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 +46 -0
- package/dist/api/app/bsky/notification/index.d.ts.map +1 -1
- package/dist/api/app/bsky/notification/index.js +2 -0
- package/dist/api/app/bsky/notification/index.js.map +1 -1
- package/dist/api/app/bsky/notification/unregisterPush.d.ts +4 -0
- package/dist/api/app/bsky/notification/unregisterPush.d.ts.map +1 -0
- package/dist/api/app/bsky/notification/unregisterPush.js +48 -0
- package/dist/api/app/bsky/notification/unregisterPush.js.map +1 -0
- package/package.json +42 -38
- package/build.templates.cjs +0 -22
- package/example.env +0 -42
- package/jest.config.cjs +0 -27
- package/src/account-manager/account-manager.ts +0 -916
- package/src/account-manager/db/index.ts +0 -21
- package/src/account-manager/db/migrations/001-init.ts +0 -115
- package/src/account-manager/db/migrations/002-account-deactivation.ts +0 -17
- package/src/account-manager/db/migrations/003-privileged-app-passwords.ts +0 -12
- package/src/account-manager/db/migrations/004-oauth.ts +0 -122
- package/src/account-manager/db/migrations/005-oauth-account-management.ts +0 -136
- package/src/account-manager/db/migrations/006-oauth-permission-sets.ts +0 -20
- package/src/account-manager/db/migrations/007-lexicon-failures-index.ts +0 -14
- package/src/account-manager/db/migrations/index.ts +0 -17
- package/src/account-manager/db/schema/account-device.ts +0 -14
- package/src/account-manager/db/schema/account.ts +0 -16
- package/src/account-manager/db/schema/actor.ts +0 -17
- package/src/account-manager/db/schema/app-password.ts +0 -13
- package/src/account-manager/db/schema/authorization-request.ts +0 -30
- package/src/account-manager/db/schema/authorized-client.ts +0 -23
- package/src/account-manager/db/schema/device.ts +0 -18
- package/src/account-manager/db/schema/email-token.ts +0 -19
- package/src/account-manager/db/schema/index.ts +0 -43
- package/src/account-manager/db/schema/invite-code.ts +0 -24
- package/src/account-manager/db/schema/lexicon.ts +0 -15
- package/src/account-manager/db/schema/refresh-token.ts +0 -11
- package/src/account-manager/db/schema/repo-root.ts +0 -12
- package/src/account-manager/db/schema/token.ts +0 -38
- package/src/account-manager/db/schema/used-refresh-token.ts +0 -13
- package/src/account-manager/helpers/account-device.ts +0 -63
- package/src/account-manager/helpers/account.ts +0 -355
- package/src/account-manager/helpers/auth.ts +0 -222
- package/src/account-manager/helpers/authorization-request.ts +0 -90
- package/src/account-manager/helpers/authorized-client.ts +0 -75
- package/src/account-manager/helpers/device.ts +0 -47
- package/src/account-manager/helpers/email-token.ts +0 -87
- package/src/account-manager/helpers/invite.ts +0 -263
- package/src/account-manager/helpers/lexicon.ts +0 -67
- package/src/account-manager/helpers/password.ts +0 -136
- package/src/account-manager/helpers/repo.ts +0 -24
- package/src/account-manager/helpers/scrypt.ts +0 -53
- package/src/account-manager/helpers/token.ts +0 -158
- package/src/account-manager/helpers/used-refresh-token.ts +0 -30
- package/src/account-manager/oauth-store.ts +0 -880
- package/src/account-manager/scope-reference-getter.ts +0 -106
- package/src/actor-store/actor-store-reader.ts +0 -45
- package/src/actor-store/actor-store-resources.ts +0 -8
- package/src/actor-store/actor-store-transactor.ts +0 -31
- package/src/actor-store/actor-store-writer.ts +0 -17
- package/src/actor-store/actor-store.ts +0 -210
- package/src/actor-store/blob/reader.ts +0 -160
- package/src/actor-store/blob/transactor.ts +0 -383
- package/src/actor-store/db/index.ts +0 -20
- package/src/actor-store/db/migrations/001-init.ts +0 -105
- package/src/actor-store/db/migrations/index.ts +0 -5
- package/src/actor-store/db/schema/account-pref.ts +0 -11
- package/src/actor-store/db/schema/backlink.ts +0 -9
- package/src/actor-store/db/schema/blob.ts +0 -14
- package/src/actor-store/db/schema/index.ts +0 -23
- package/src/actor-store/db/schema/record-blob.ts +0 -8
- package/src/actor-store/db/schema/record.ts +0 -14
- package/src/actor-store/db/schema/repo-block.ts +0 -10
- package/src/actor-store/db/schema/repo-root.ts +0 -10
- package/src/actor-store/migrate.ts +0 -39
- package/src/actor-store/preference/reader.ts +0 -48
- package/src/actor-store/preference/transactor.ts +0 -55
- package/src/actor-store/preference/util.ts +0 -39
- package/src/actor-store/record/reader.ts +0 -374
- package/src/actor-store/record/transactor.ts +0 -111
- package/src/actor-store/repo/reader.ts +0 -31
- package/src/actor-store/repo/sql-repo-reader.ts +0 -150
- package/src/actor-store/repo/sql-repo-transactor.ts +0 -105
- package/src/actor-store/repo/transactor.ts +0 -227
- package/src/api/app/bsky/actor/getPreferences.ts +0 -57
- package/src/api/app/bsky/actor/getProfile.ts +0 -41
- package/src/api/app/bsky/actor/getProfiles.ts +0 -51
- package/src/api/app/bsky/actor/index.ts +0 -13
- package/src/api/app/bsky/actor/putPreferences.ts +0 -62
- package/src/api/app/bsky/feed/getActorLikes.ts +0 -63
- package/src/api/app/bsky/feed/getAuthorFeed.ts +0 -84
- package/src/api/app/bsky/feed/getFeed.ts +0 -47
- package/src/api/app/bsky/feed/getPostThread.ts +0 -251
- package/src/api/app/bsky/feed/getTimeline.ts +0 -50
- package/src/api/app/bsky/feed/index.ts +0 -15
- package/src/api/app/bsky/index.ts +0 -11
- package/src/api/app/bsky/notification/index.ts +0 -7
- package/src/api/app/bsky/notification/registerPush.ts +0 -71
- package/src/api/app/bsky/util/resolver.ts +0 -20
- package/src/api/com/atproto/admin/deleteAccount.ts +0 -22
- package/src/api/com/atproto/admin/disableAccountInvites.ts +0 -18
- package/src/api/com/atproto/admin/disableInviteCodes.ts +0 -21
- package/src/api/com/atproto/admin/enableAccountInvites.ts +0 -18
- package/src/api/com/atproto/admin/getAccountInfo.ts +0 -32
- package/src/api/com/atproto/admin/getAccountInfos.ts +0 -34
- package/src/api/com/atproto/admin/getInviteCodes.ts +0 -126
- package/src/api/com/atproto/admin/getSubjectStatus.ts +0 -76
- package/src/api/com/atproto/admin/index.ts +0 -31
- package/src/api/com/atproto/admin/sendEmail.ts +0 -47
- package/src/api/com/atproto/admin/updateAccountEmail.ts +0 -32
- package/src/api/com/atproto/admin/updateAccountHandle.ts +0 -47
- package/src/api/com/atproto/admin/updateAccountPassword.ts +0 -34
- package/src/api/com/atproto/admin/updateSubjectStatus.ts +0 -68
- package/src/api/com/atproto/admin/util.ts +0 -66
- package/src/api/com/atproto/identity/getRecommendedDidCredentials.ts +0 -50
- package/src/api/com/atproto/identity/index.ts +0 -17
- package/src/api/com/atproto/identity/requestPlcOperationSignature.ts +0 -59
- package/src/api/com/atproto/identity/resolveHandle.ts +0 -50
- package/src/api/com/atproto/identity/signPlcOperation.ts +0 -85
- package/src/api/com/atproto/identity/submitPlcOperation.ts +0 -65
- package/src/api/com/atproto/identity/updateHandle.ts +0 -66
- package/src/api/com/atproto/index.ts +0 -19
- package/src/api/com/atproto/moderation/createReport.ts +0 -41
- package/src/api/com/atproto/moderation/index.ts +0 -7
- package/src/api/com/atproto/repo/applyWrites.ts +0 -226
- package/src/api/com/atproto/repo/createRecord.ts +0 -143
- package/src/api/com/atproto/repo/deleteRecord.ts +0 -122
- package/src/api/com/atproto/repo/describeRepo.ts +0 -43
- package/src/api/com/atproto/repo/getRecord.ts +0 -40
- package/src/api/com/atproto/repo/importRepo.ts +0 -101
- package/src/api/com/atproto/repo/index.ts +0 -25
- package/src/api/com/atproto/repo/listMissingBlobs.ts +0 -29
- package/src/api/com/atproto/repo/listRecords.ts +0 -36
- package/src/api/com/atproto/repo/putRecord.ts +0 -211
- package/src/api/com/atproto/repo/uploadBlob.ts +0 -60
- package/src/api/com/atproto/server/activateAccount.ts +0 -37
- package/src/api/com/atproto/server/checkAccountStatus.ts +0 -51
- package/src/api/com/atproto/server/confirmEmail.ts +0 -39
- package/src/api/com/atproto/server/createAccount.ts +0 -327
- package/src/api/com/atproto/server/createAppPassword.ts +0 -53
- package/src/api/com/atproto/server/createInviteCode.ts +0 -38
- package/src/api/com/atproto/server/createInviteCodes.ts +0 -42
- package/src/api/com/atproto/server/createSession.ts +0 -97
- package/src/api/com/atproto/server/deactivateAccount.ts +0 -41
- package/src/api/com/atproto/server/deleteAccount.ts +0 -85
- package/src/api/com/atproto/server/deleteSession.ts +0 -23
- package/src/api/com/atproto/server/describeServer.ts +0 -29
- package/src/api/com/atproto/server/getAccountInviteCodes.ts +0 -142
- package/src/api/com/atproto/server/getServiceAuth.ts +0 -111
- package/src/api/com/atproto/server/getSession.ts +0 -80
- package/src/api/com/atproto/server/index.ts +0 -55
- package/src/api/com/atproto/server/listAppPasswords.ts +0 -45
- package/src/api/com/atproto/server/refreshSession.ts +0 -72
- package/src/api/com/atproto/server/requestAccountDelete.ts +0 -66
- package/src/api/com/atproto/server/requestEmailConfirmation.ts +0 -68
- package/src/api/com/atproto/server/requestEmailUpdate.ts +0 -86
- package/src/api/com/atproto/server/requestPasswordReset.ts +0 -52
- package/src/api/com/atproto/server/reserveSigningKey.ts +0 -15
- package/src/api/com/atproto/server/resetPassword.ts +0 -50
- package/src/api/com/atproto/server/revokeAppPassword.ts +0 -42
- package/src/api/com/atproto/server/updateEmail.ts +0 -52
- package/src/api/com/atproto/server/util.ts +0 -136
- package/src/api/com/atproto/sync/deprecated/getCheckout.ts +0 -27
- package/src/api/com/atproto/sync/deprecated/getHead.ts +0 -33
- package/src/api/com/atproto/sync/getBlob.ts +0 -61
- package/src/api/com/atproto/sync/getBlocks.ts +0 -37
- package/src/api/com/atproto/sync/getLatestCommit.ts +0 -33
- package/src/api/com/atproto/sync/getRecord.ts +0 -49
- package/src/api/com/atproto/sync/getRepo.ts +0 -75
- package/src/api/com/atproto/sync/getRepoStatus.ts +0 -34
- package/src/api/com/atproto/sync/index.ts +0 -27
- package/src/api/com/atproto/sync/listBlobs.ts +0 -33
- package/src/api/com/atproto/sync/listRepos.ts +0 -74
- package/src/api/com/atproto/sync/subscribeRepos.ts +0 -73
- package/src/api/com/atproto/sync/util.ts +0 -37
- package/src/api/com/atproto/temp/checkSignupQueue.ts +0 -34
- package/src/api/com/atproto/temp/index.ts +0 -7
- package/src/api/index.ts +0 -10
- package/src/api/proxy.ts +0 -44
- package/src/app-view.ts +0 -24
- package/src/auth-output.ts +0 -52
- package/src/auth-routes.ts +0 -64
- package/src/auth-scope.ts +0 -40
- package/src/auth-verifier.ts +0 -668
- package/src/background.ts +0 -65
- package/src/basic-routes.ts +0 -52
- package/src/bsky-app-view.ts +0 -33
- package/src/config/config.ts +0 -553
- package/src/config/env.ts +0 -167
- package/src/config/index.ts +0 -3
- package/src/config/secrets.ts +0 -54
- package/src/context.ts +0 -523
- package/src/crawlers.ts +0 -46
- package/src/db/cast.ts +0 -52
- package/src/db/db.ts +0 -140
- package/src/db/index.ts +0 -4
- package/src/db/migrator.ts +0 -40
- package/src/db/pagination.ts +0 -132
- package/src/db/tables/moderation.ts +0 -80
- package/src/db/util.ts +0 -108
- package/src/did-cache/db/index.ts +0 -21
- package/src/did-cache/db/migrations.ts +0 -17
- package/src/did-cache/db/schema.ts +0 -9
- package/src/did-cache/index.ts +0 -131
- package/src/disk-blobstore.ts +0 -172
- package/src/error.ts +0 -19
- package/src/handle/explicit-slurs.ts +0 -22
- package/src/handle/index.ts +0 -49
- package/src/handle/reserved.ts +0 -1059
- package/src/image/image-url-builder.ts +0 -16
- package/src/index.ts +0 -189
- package/src/lexicons.ts +0 -4
- package/src/logger.ts +0 -35
- package/src/mailer/index.ts +0 -111
- package/src/mailer/moderation.ts +0 -33
- package/src/mailer/templates/confirm-email.d.ts +0 -4
- package/src/mailer/templates/confirm-email.hbs +0 -158
- package/src/mailer/templates/delete-account.d.ts +0 -4
- package/src/mailer/templates/delete-account.hbs +0 -156
- package/src/mailer/templates/plc-operation.d.ts +0 -4
- package/src/mailer/templates/plc-operation.hbs +0 -153
- package/src/mailer/templates/reset-password.d.ts +0 -4
- package/src/mailer/templates/reset-password.hbs +0 -154
- package/src/mailer/templates/update-email.d.ts +0 -4
- package/src/mailer/templates/update-email.hbs +0 -153
- package/src/mailer/templates.ts +0 -17
- package/src/pipethrough.ts +0 -716
- package/src/rate-limits.ts +0 -59
- package/src/read-after-write/index.ts +0 -3
- package/src/read-after-write/types.ts +0 -35
- package/src/read-after-write/util.ts +0 -101
- package/src/read-after-write/viewer.ts +0 -290
- package/src/redis.ts +0 -25
- package/src/repo/index.ts +0 -2
- package/src/repo/prepare.ts +0 -266
- package/src/repo/types.ts +0 -65
- package/src/scripts/README.md +0 -40
- package/src/scripts/index.ts +0 -20
- package/src/scripts/publish-identity.ts +0 -60
- package/src/scripts/rebuild-repo.ts +0 -119
- package/src/scripts/rotate-keys.ts +0 -146
- package/src/scripts/sequencer-recovery/index.ts +0 -23
- package/src/scripts/sequencer-recovery/recoverer.ts +0 -297
- package/src/scripts/sequencer-recovery/recovery-db.ts +0 -65
- package/src/scripts/sequencer-recovery/repair-repos.ts +0 -49
- package/src/scripts/sequencer-recovery/user-queues.ts +0 -44
- package/src/scripts/util.ts +0 -7
- package/src/sequencer/db/index.ts +0 -21
- package/src/sequencer/db/migrations/001-init.ts +0 -35
- package/src/sequencer/db/migrations/index.ts +0 -5
- package/src/sequencer/db/schema.ts +0 -19
- package/src/sequencer/events.ts +0 -199
- package/src/sequencer/index.ts +0 -3
- package/src/sequencer/outbox.ts +0 -123
- package/src/sequencer/sequencer.ts +0 -290
- package/src/util/compression.ts +0 -16
- package/src/util/debug.ts +0 -10
- package/src/util/http.ts +0 -31
- package/src/util/types.ts +0 -7
- package/src/well-known.ts +0 -30
- package/test.env +0 -2
- package/tests/__snapshots__/takedown-appeal.test.ts.snap +0 -43
- package/tests/_oauth_client_assets_middleware.ts +0 -23
- package/tests/_puppeteer.ts +0 -147
- package/tests/_types.d.ts +0 -16
- package/tests/_util.ts +0 -191
- package/tests/account-deactivation.test.ts +0 -204
- package/tests/account-deletion.test.ts +0 -300
- package/tests/account-manager.test.ts +0 -462
- package/tests/account-migration.test.ts +0 -221
- package/tests/account-status.test.ts +0 -206
- package/tests/account.test.ts +0 -595
- package/tests/app-passwords.test.ts +0 -262
- package/tests/auth.test.ts +0 -405
- package/tests/blob-deletes.test.ts +0 -204
- package/tests/create-post.test.ts +0 -79
- package/tests/crud.test.ts +0 -1595
- package/tests/db.test.ts +0 -170
- package/tests/email-confirmation.test.ts +0 -227
- package/tests/entryway-mock.ts +0 -323
- package/tests/entryway.test.ts +0 -145
- package/tests/file-uploads.test.ts +0 -301
- package/tests/get-service-auth.test.ts +0 -81
- package/tests/handle-validation.test.ts +0 -56
- package/tests/handles.test.ts +0 -274
- package/tests/invite-codes.test.ts +0 -367
- package/tests/invites-admin.test.ts +0 -252
- package/tests/moderation.test.ts +0 -280
- package/tests/moderator-auth.test.ts +0 -177
- package/tests/oauth.test.ts +0 -334
- package/tests/plc-operations.test.ts +0 -239
- package/tests/preferences.test.ts +0 -352
- package/tests/proxied/__snapshots__/admin.test.ts.snap +0 -516
- package/tests/proxied/__snapshots__/feedgen.test.ts.snap +0 -215
- package/tests/proxied/__snapshots__/views.test.ts.snap +0 -4456
- package/tests/proxied/admin.test.ts +0 -340
- package/tests/proxied/feedgen.test.ts +0 -66
- package/tests/proxied/notif.test.ts +0 -85
- package/tests/proxied/procedures.test.ts +0 -175
- package/tests/proxied/proxy-catchall.test.ts +0 -256
- package/tests/proxied/proxy-header.test.ts +0 -239
- package/tests/proxied/proxy-oauth-aud.test.ts +0 -182
- package/tests/proxied/read-after-write.test.ts +0 -382
- package/tests/proxied/views.test.ts +0 -608
- package/tests/races.test.ts +0 -89
- package/tests/rate-limits.test.ts +0 -70
- package/tests/recovery.test.ts +0 -180
- package/tests/seeds/basic.ts +0 -165
- package/tests/seeds/follows.ts +0 -57
- package/tests/seeds/likes.ts +0 -14
- package/tests/seeds/reposts.ts +0 -18
- package/tests/seeds/thread.ts +0 -40
- package/tests/seeds/users-bulk.ts +0 -246
- package/tests/seeds/users.ts +0 -67
- package/tests/sequencer.test.ts +0 -251
- package/tests/server.test.ts +0 -151
- package/tests/sync/invertible-ops.test.ts +0 -99
- package/tests/sync/list.test.ts +0 -43
- package/tests/sync/subscribe-repos.test.ts +0 -672
- package/tests/sync/sync.test.ts +0 -316
- package/tests/takedown-appeal.test.ts +0 -166
- package/tsconfig.build.json +0 -9
- package/tsconfig.build.tsbuildinfo +0 -1
- package/tsconfig.json +0 -7
- package/tsconfig.tests.json +0 -8
|
@@ -1,262 +0,0 @@
|
|
|
1
|
-
import * as jose from 'jose'
|
|
2
|
-
import { AtpAgent } from '@atproto/api'
|
|
3
|
-
import { TestNetworkNoAppView } from '@atproto/dev-env'
|
|
4
|
-
|
|
5
|
-
describe('app_passwords', () => {
|
|
6
|
-
let network: TestNetworkNoAppView
|
|
7
|
-
let accntAgent: AtpAgent
|
|
8
|
-
let appAgent: AtpAgent
|
|
9
|
-
let priviAgent: AtpAgent
|
|
10
|
-
|
|
11
|
-
beforeAll(async () => {
|
|
12
|
-
network = await TestNetworkNoAppView.create({
|
|
13
|
-
dbPostgresSchema: 'app_passwords',
|
|
14
|
-
})
|
|
15
|
-
accntAgent = network.pds.getAgent()
|
|
16
|
-
appAgent = network.pds.getAgent()
|
|
17
|
-
priviAgent = network.pds.getAgent()
|
|
18
|
-
|
|
19
|
-
await accntAgent.createAccount({
|
|
20
|
-
handle: 'alice.test',
|
|
21
|
-
email: 'alice@test.com',
|
|
22
|
-
password: 'alice-pass',
|
|
23
|
-
})
|
|
24
|
-
})
|
|
25
|
-
|
|
26
|
-
afterAll(async () => {
|
|
27
|
-
await network?.close()
|
|
28
|
-
})
|
|
29
|
-
|
|
30
|
-
let appPass: string
|
|
31
|
-
let privilegedAppPass: string
|
|
32
|
-
|
|
33
|
-
it('creates an app-specific password', async () => {
|
|
34
|
-
const res = await accntAgent.api.com.atproto.server.createAppPassword({
|
|
35
|
-
name: 'test-pass',
|
|
36
|
-
})
|
|
37
|
-
expect(res.data.name).toBe('test-pass')
|
|
38
|
-
expect(res.data.privileged).toBe(false)
|
|
39
|
-
appPass = res.data.password
|
|
40
|
-
})
|
|
41
|
-
|
|
42
|
-
it('creates a privileged app-specific password', async () => {
|
|
43
|
-
const res = await accntAgent.api.com.atproto.server.createAppPassword({
|
|
44
|
-
name: 'privi-pass',
|
|
45
|
-
privileged: true,
|
|
46
|
-
})
|
|
47
|
-
expect(res.data.name).toBe('privi-pass')
|
|
48
|
-
expect(res.data.privileged).toBe(true)
|
|
49
|
-
privilegedAppPass = res.data.password
|
|
50
|
-
})
|
|
51
|
-
|
|
52
|
-
it('creates a session with an app-specific password', async () => {
|
|
53
|
-
const res1 = await appAgent.login({
|
|
54
|
-
identifier: 'alice.test',
|
|
55
|
-
password: appPass,
|
|
56
|
-
})
|
|
57
|
-
expect(res1.data.did).toEqual(accntAgent.session?.did)
|
|
58
|
-
const res2 = await priviAgent.login({
|
|
59
|
-
identifier: 'alice.test',
|
|
60
|
-
password: privilegedAppPass,
|
|
61
|
-
})
|
|
62
|
-
expect(res2.data.did).toEqual(accntAgent.session?.did)
|
|
63
|
-
})
|
|
64
|
-
|
|
65
|
-
it('creates an access token for an app with a restricted scope', () => {
|
|
66
|
-
const decoded = jose.decodeJwt(appAgent.session?.accessJwt ?? '')
|
|
67
|
-
expect(decoded?.scope).toEqual('com.atproto.appPass')
|
|
68
|
-
|
|
69
|
-
const decodedPrivi = jose.decodeJwt(priviAgent.session?.accessJwt ?? '')
|
|
70
|
-
expect(decodedPrivi?.scope).toEqual('com.atproto.appPassPrivileged')
|
|
71
|
-
})
|
|
72
|
-
|
|
73
|
-
it('allows actions to be performed from app', async () => {
|
|
74
|
-
await appAgent.api.app.bsky.feed.post.create(
|
|
75
|
-
{
|
|
76
|
-
repo: appAgent.assertDid,
|
|
77
|
-
},
|
|
78
|
-
{
|
|
79
|
-
text: 'Testing testing',
|
|
80
|
-
createdAt: new Date().toISOString(),
|
|
81
|
-
},
|
|
82
|
-
)
|
|
83
|
-
await priviAgent.api.app.bsky.feed.post.create(
|
|
84
|
-
{
|
|
85
|
-
repo: priviAgent.assertDid,
|
|
86
|
-
},
|
|
87
|
-
{
|
|
88
|
-
text: 'testing again',
|
|
89
|
-
createdAt: new Date().toISOString(),
|
|
90
|
-
},
|
|
91
|
-
)
|
|
92
|
-
})
|
|
93
|
-
|
|
94
|
-
it('restricts full access actions', async () => {
|
|
95
|
-
const attempt1 = appAgent.api.com.atproto.server.createAppPassword({
|
|
96
|
-
name: 'another-one',
|
|
97
|
-
})
|
|
98
|
-
await expect(attempt1).rejects.toThrow('Bad token scope')
|
|
99
|
-
const attempt2 = priviAgent.api.com.atproto.server.createAppPassword({
|
|
100
|
-
name: 'another-one',
|
|
101
|
-
})
|
|
102
|
-
await expect(attempt2).rejects.toThrow('Bad token scope')
|
|
103
|
-
})
|
|
104
|
-
|
|
105
|
-
it('restricts privileged app password actions', async () => {
|
|
106
|
-
const attempt = appAgent.api.chat.bsky.convo.listConvos({})
|
|
107
|
-
await expect(attempt).rejects.toThrow('Bad token method')
|
|
108
|
-
})
|
|
109
|
-
|
|
110
|
-
it('restricts privileged app password actions', async () => {
|
|
111
|
-
const attempt = appAgent.api.chat.bsky.convo.listConvos()
|
|
112
|
-
await expect(attempt).rejects.toThrow('Bad token method')
|
|
113
|
-
})
|
|
114
|
-
|
|
115
|
-
it('restricts service auth token methods for non-privileged access tokens', async () => {
|
|
116
|
-
const attemptCaseSensitive = appAgent.api.com.atproto.server.getServiceAuth(
|
|
117
|
-
{
|
|
118
|
-
aud: network.pds.ctx.cfg.service.did,
|
|
119
|
-
lxm: 'com.atproto.server.createAccount',
|
|
120
|
-
},
|
|
121
|
-
)
|
|
122
|
-
await expect(attemptCaseSensitive).rejects.toThrow(
|
|
123
|
-
/insufficient access to request a service auth token for the following method/,
|
|
124
|
-
)
|
|
125
|
-
const attemptCaseInsensitive =
|
|
126
|
-
appAgent.api.com.atproto.server.getServiceAuth({
|
|
127
|
-
aud: network.pds.ctx.cfg.service.did,
|
|
128
|
-
lxm: 'com.atproto.server.createaccount',
|
|
129
|
-
})
|
|
130
|
-
await expect(attemptCaseInsensitive).rejects.toThrow(
|
|
131
|
-
/insufficient access to request a service auth token for the following method/,
|
|
132
|
-
)
|
|
133
|
-
})
|
|
134
|
-
|
|
135
|
-
it('allows privileged service auth token scopes for privileged access tokens', async () => {
|
|
136
|
-
await priviAgent.api.com.atproto.server.getServiceAuth({
|
|
137
|
-
aud: network.pds.ctx.cfg.service.did,
|
|
138
|
-
lxm: 'com.atproto.server.createAccount',
|
|
139
|
-
})
|
|
140
|
-
})
|
|
141
|
-
|
|
142
|
-
it('persists scope across refreshes', async () => {
|
|
143
|
-
const session = await appAgent.api.com.atproto.server.refreshSession(
|
|
144
|
-
undefined,
|
|
145
|
-
{
|
|
146
|
-
headers: {
|
|
147
|
-
authorization: `Bearer ${appAgent.session?.refreshJwt}`,
|
|
148
|
-
},
|
|
149
|
-
},
|
|
150
|
-
)
|
|
151
|
-
|
|
152
|
-
// allows any access auth
|
|
153
|
-
await appAgent.api.app.bsky.feed.post.create(
|
|
154
|
-
{
|
|
155
|
-
repo: appAgent.assertDid,
|
|
156
|
-
},
|
|
157
|
-
{
|
|
158
|
-
text: 'Testing testing',
|
|
159
|
-
createdAt: new Date().toISOString(),
|
|
160
|
-
},
|
|
161
|
-
{
|
|
162
|
-
authorization: `Bearer ${session.data.accessJwt}`,
|
|
163
|
-
},
|
|
164
|
-
)
|
|
165
|
-
|
|
166
|
-
// allows privileged app passwords or higher
|
|
167
|
-
const priviAttempt = appAgent.api.com.atproto.server.getServiceAuth({
|
|
168
|
-
aud: network.pds.ctx.cfg.service.did,
|
|
169
|
-
lxm: 'com.atproto.server.createAccount',
|
|
170
|
-
})
|
|
171
|
-
await expect(priviAttempt).rejects.toThrow(
|
|
172
|
-
/insufficient access to request a service auth token for the following method/,
|
|
173
|
-
)
|
|
174
|
-
|
|
175
|
-
// allows only full access auth
|
|
176
|
-
const fullAttempt = appAgent.api.com.atproto.server.createAppPassword(
|
|
177
|
-
{
|
|
178
|
-
name: 'another-one',
|
|
179
|
-
},
|
|
180
|
-
{
|
|
181
|
-
encoding: 'application/json',
|
|
182
|
-
headers: { authorization: `Bearer ${session.data.accessJwt}` },
|
|
183
|
-
},
|
|
184
|
-
)
|
|
185
|
-
await expect(fullAttempt).rejects.toThrow('Bad token scope')
|
|
186
|
-
})
|
|
187
|
-
|
|
188
|
-
it('persists privileged scope across refreshes', async () => {
|
|
189
|
-
const session = await priviAgent.api.com.atproto.server.refreshSession(
|
|
190
|
-
undefined,
|
|
191
|
-
{
|
|
192
|
-
headers: {
|
|
193
|
-
authorization: `Bearer ${priviAgent.session?.refreshJwt}`,
|
|
194
|
-
},
|
|
195
|
-
},
|
|
196
|
-
)
|
|
197
|
-
|
|
198
|
-
// allows any access auth
|
|
199
|
-
await priviAgent.api.app.bsky.feed.post.create(
|
|
200
|
-
{
|
|
201
|
-
repo: priviAgent.assertDid,
|
|
202
|
-
},
|
|
203
|
-
{
|
|
204
|
-
text: 'Testing testing',
|
|
205
|
-
createdAt: new Date().toISOString(),
|
|
206
|
-
},
|
|
207
|
-
{
|
|
208
|
-
authorization: `Bearer ${session.data.accessJwt}`,
|
|
209
|
-
},
|
|
210
|
-
)
|
|
211
|
-
|
|
212
|
-
// allows privileged app passwords or higher
|
|
213
|
-
await priviAgent.api.com.atproto.server.getServiceAuth({
|
|
214
|
-
aud: network.pds.ctx.cfg.service.did,
|
|
215
|
-
})
|
|
216
|
-
|
|
217
|
-
// allows only full access auth
|
|
218
|
-
const attempt = priviAgent.api.com.atproto.server.createAppPassword(
|
|
219
|
-
{
|
|
220
|
-
name: 'another-one',
|
|
221
|
-
},
|
|
222
|
-
{
|
|
223
|
-
encoding: 'application/json',
|
|
224
|
-
headers: { authorization: `Bearer ${session.data.accessJwt}` },
|
|
225
|
-
},
|
|
226
|
-
)
|
|
227
|
-
await expect(attempt).rejects.toThrow('Bad token scope')
|
|
228
|
-
})
|
|
229
|
-
|
|
230
|
-
it('lists available app-specific passwords', async () => {
|
|
231
|
-
const res = await appAgent.api.com.atproto.server.listAppPasswords()
|
|
232
|
-
expect(res.data.passwords.length).toBe(2)
|
|
233
|
-
expect(res.data.passwords[0].name).toEqual('privi-pass')
|
|
234
|
-
expect(res.data.passwords[0].privileged).toEqual(true)
|
|
235
|
-
expect(res.data.passwords[1].name).toEqual('test-pass')
|
|
236
|
-
expect(res.data.passwords[1].privileged).toEqual(false)
|
|
237
|
-
})
|
|
238
|
-
|
|
239
|
-
it('revokes an app-specific password', async () => {
|
|
240
|
-
await appAgent.api.com.atproto.server.revokeAppPassword({
|
|
241
|
-
name: 'test-pass',
|
|
242
|
-
})
|
|
243
|
-
})
|
|
244
|
-
|
|
245
|
-
it('no longer allows session refresh after revocation', async () => {
|
|
246
|
-
const attempt = appAgent.api.com.atproto.server.refreshSession(undefined, {
|
|
247
|
-
headers: {
|
|
248
|
-
authorization: `Bearer ${appAgent.session?.refreshJwt}`,
|
|
249
|
-
},
|
|
250
|
-
})
|
|
251
|
-
await expect(attempt).rejects.toThrow('Token has been revoked')
|
|
252
|
-
})
|
|
253
|
-
|
|
254
|
-
it('no longer allows session creation after revocation', async () => {
|
|
255
|
-
const newAgent = network.pds.getAgent()
|
|
256
|
-
const attempt = newAgent.login({
|
|
257
|
-
identifier: 'alice.test',
|
|
258
|
-
password: appPass,
|
|
259
|
-
})
|
|
260
|
-
await expect(attempt).rejects.toThrow('Invalid identifier or password')
|
|
261
|
-
})
|
|
262
|
-
})
|
package/tests/auth.test.ts
DELETED
|
@@ -1,405 +0,0 @@
|
|
|
1
|
-
import * as jose from 'jose'
|
|
2
|
-
import { request as undiciRequest } from 'undici'
|
|
3
|
-
import { AtpAgent } from '@atproto/api'
|
|
4
|
-
import { SeedClient, TestNetworkNoAppView } from '@atproto/dev-env'
|
|
5
|
-
import { createRefreshToken } from '../src/account-manager/helpers/auth.js'
|
|
6
|
-
|
|
7
|
-
describe('auth', () => {
|
|
8
|
-
let network: TestNetworkNoAppView
|
|
9
|
-
let agent: AtpAgent
|
|
10
|
-
|
|
11
|
-
beforeAll(async () => {
|
|
12
|
-
network = await TestNetworkNoAppView.create({
|
|
13
|
-
dbPostgresSchema: 'auth',
|
|
14
|
-
})
|
|
15
|
-
agent = network.pds.getAgent()
|
|
16
|
-
})
|
|
17
|
-
|
|
18
|
-
afterAll(async () => {
|
|
19
|
-
await network?.close()
|
|
20
|
-
})
|
|
21
|
-
|
|
22
|
-
const createAccount = async (info) => {
|
|
23
|
-
const { data } = await agent.com.atproto.server.createAccount(info)
|
|
24
|
-
return data
|
|
25
|
-
}
|
|
26
|
-
const getSession = async (jwt) => {
|
|
27
|
-
const { data } = await agent.com.atproto.server.getSession(
|
|
28
|
-
{},
|
|
29
|
-
{
|
|
30
|
-
headers: SeedClient.getHeaders(jwt),
|
|
31
|
-
},
|
|
32
|
-
)
|
|
33
|
-
return data
|
|
34
|
-
}
|
|
35
|
-
const createSession = async (info) => {
|
|
36
|
-
const { data } = await agent.com.atproto.server.createSession(info)
|
|
37
|
-
return data
|
|
38
|
-
}
|
|
39
|
-
const deleteSession = async (jwt) => {
|
|
40
|
-
await agent.com.atproto.server.deleteSession(undefined, {
|
|
41
|
-
headers: SeedClient.getHeaders(jwt),
|
|
42
|
-
})
|
|
43
|
-
}
|
|
44
|
-
const refreshSession = async (jwt: string) => {
|
|
45
|
-
const { data } = await agent.com.atproto.server.refreshSession(undefined, {
|
|
46
|
-
headers: SeedClient.getHeaders(jwt),
|
|
47
|
-
})
|
|
48
|
-
return data
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
it('provides valid access and refresh token on account creation.', async () => {
|
|
52
|
-
const email = 'alice@test.com'
|
|
53
|
-
const account = await createAccount({
|
|
54
|
-
handle: 'alice.test',
|
|
55
|
-
email,
|
|
56
|
-
password: 'password',
|
|
57
|
-
})
|
|
58
|
-
// Valid access token
|
|
59
|
-
const sessionInfo = await getSession(account.accessJwt)
|
|
60
|
-
expect(sessionInfo).toEqual({
|
|
61
|
-
did: account.did,
|
|
62
|
-
handle: account.handle,
|
|
63
|
-
email,
|
|
64
|
-
emailConfirmed: false,
|
|
65
|
-
active: true,
|
|
66
|
-
})
|
|
67
|
-
// Valid refresh token
|
|
68
|
-
const nextSession = await refreshSession(account.refreshJwt)
|
|
69
|
-
expect(nextSession).toEqual(
|
|
70
|
-
expect.objectContaining({
|
|
71
|
-
did: account.did,
|
|
72
|
-
handle: account.handle,
|
|
73
|
-
}),
|
|
74
|
-
)
|
|
75
|
-
})
|
|
76
|
-
|
|
77
|
-
it('provides valid access and refresh token on session creation.', async () => {
|
|
78
|
-
const email = 'bob@test.com'
|
|
79
|
-
await createAccount({
|
|
80
|
-
handle: 'bob.test',
|
|
81
|
-
email,
|
|
82
|
-
password: 'password',
|
|
83
|
-
})
|
|
84
|
-
const session = await createSession({
|
|
85
|
-
identifier: 'bob.test',
|
|
86
|
-
password: 'password',
|
|
87
|
-
})
|
|
88
|
-
// Valid access token
|
|
89
|
-
const sessionInfo = await getSession(session.accessJwt)
|
|
90
|
-
expect(sessionInfo).toEqual({
|
|
91
|
-
did: session.did,
|
|
92
|
-
handle: session.handle,
|
|
93
|
-
email,
|
|
94
|
-
emailConfirmed: false,
|
|
95
|
-
active: true,
|
|
96
|
-
})
|
|
97
|
-
// Valid refresh token
|
|
98
|
-
const nextSession = await refreshSession(session.refreshJwt)
|
|
99
|
-
expect(nextSession).toEqual(
|
|
100
|
-
expect.objectContaining({
|
|
101
|
-
did: session.did,
|
|
102
|
-
handle: session.handle,
|
|
103
|
-
}),
|
|
104
|
-
)
|
|
105
|
-
})
|
|
106
|
-
|
|
107
|
-
it('allows session creation using email address.', async () => {
|
|
108
|
-
const session = await createSession({
|
|
109
|
-
identifier: 'bob@TEST.com',
|
|
110
|
-
password: 'password',
|
|
111
|
-
})
|
|
112
|
-
expect(session.handle).toEqual('bob.test')
|
|
113
|
-
})
|
|
114
|
-
|
|
115
|
-
it('fails on session creation with a bad password.', async () => {
|
|
116
|
-
const sessionPromise = createSession({
|
|
117
|
-
identifier: 'bob.test',
|
|
118
|
-
password: 'wrong-pass',
|
|
119
|
-
})
|
|
120
|
-
await expect(sessionPromise).rejects.toThrow(
|
|
121
|
-
'Invalid identifier or password',
|
|
122
|
-
)
|
|
123
|
-
})
|
|
124
|
-
|
|
125
|
-
it('returns identical error responses for unknown identifier and known-identifier-with-wrong-password.', async () => {
|
|
126
|
-
const probe = async (info: { identifier: string; password: string }) => {
|
|
127
|
-
const res = await fetch(
|
|
128
|
-
`${network.pds.url}/xrpc/com.atproto.server.createSession`,
|
|
129
|
-
{
|
|
130
|
-
method: 'POST',
|
|
131
|
-
headers: { 'content-type': 'application/json' },
|
|
132
|
-
body: JSON.stringify(info),
|
|
133
|
-
},
|
|
134
|
-
)
|
|
135
|
-
return { status: res.status, body: await res.json() }
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
// bob.test was created above with password 'password'.
|
|
139
|
-
const unknownIdentifier = await probe({
|
|
140
|
-
identifier: 'no-such-user.test',
|
|
141
|
-
password: 'any-password',
|
|
142
|
-
})
|
|
143
|
-
const knownIdentifierWrongPassword = await probe({
|
|
144
|
-
identifier: 'bob.test',
|
|
145
|
-
password: 'wrong-password',
|
|
146
|
-
})
|
|
147
|
-
|
|
148
|
-
expect(knownIdentifierWrongPassword).toEqual(unknownIdentifier)
|
|
149
|
-
expect(unknownIdentifier).toEqual({
|
|
150
|
-
status: 401,
|
|
151
|
-
body: {
|
|
152
|
-
error: 'AuthenticationRequired',
|
|
153
|
-
message: 'Invalid identifier or password',
|
|
154
|
-
},
|
|
155
|
-
})
|
|
156
|
-
})
|
|
157
|
-
|
|
158
|
-
it('returns identical error responses for unknown identifier and known-identifier-with-wrong-password in the OAuth sign-in flow.', async () => {
|
|
159
|
-
const issuer = new URL(network.pds.url)
|
|
160
|
-
const csrfToken = 'a'.repeat(24)
|
|
161
|
-
const probe = async (credentials: {
|
|
162
|
-
username: string
|
|
163
|
-
password: string
|
|
164
|
-
}) => {
|
|
165
|
-
// @NOTE We use undici's low-level `request` rather than fetch(),
|
|
166
|
-
// because the WHATWG fetch API treats `sec-fetch-*` as forbidden
|
|
167
|
-
// request headers and silently overwrites them with its own values
|
|
168
|
-
// (notably `sec-fetch-mode: cors` in Node). The endpoint requires
|
|
169
|
-
// `same-origin` here, so we need raw header control.
|
|
170
|
-
const res = await undiciRequest(
|
|
171
|
-
`${issuer.origin}/@atproto/oauth-provider/~api/sign-in`,
|
|
172
|
-
{
|
|
173
|
-
method: 'POST',
|
|
174
|
-
headers: {
|
|
175
|
-
'content-type': 'application/json',
|
|
176
|
-
// The endpoint restricts fetches to same-origin navigations
|
|
177
|
-
// from either `/oauth/authorize` or `/account[/*]`. Use the
|
|
178
|
-
// first-party `/account` path so we don't need a live OAuth
|
|
179
|
-
// authorization request to exist in the request store.
|
|
180
|
-
'sec-fetch-mode': 'same-origin',
|
|
181
|
-
'sec-fetch-site': 'same-origin',
|
|
182
|
-
origin: issuer.origin,
|
|
183
|
-
referer: `${issuer.origin}/account`,
|
|
184
|
-
'x-csrf-token': csrfToken,
|
|
185
|
-
cookie: `csrf-token=${csrfToken}`,
|
|
186
|
-
},
|
|
187
|
-
body: JSON.stringify({ locale: 'en', ...credentials }),
|
|
188
|
-
},
|
|
189
|
-
)
|
|
190
|
-
return { status: res.statusCode, body: await res.body.json() }
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
// bob.test was created above with password 'password'.
|
|
194
|
-
const unknownIdentifier = await probe({
|
|
195
|
-
username: 'no-such-user.test',
|
|
196
|
-
password: 'any-password',
|
|
197
|
-
})
|
|
198
|
-
const knownIdentifierWrongPassword = await probe({
|
|
199
|
-
username: 'bob.test',
|
|
200
|
-
password: 'wrong-password',
|
|
201
|
-
})
|
|
202
|
-
|
|
203
|
-
expect(knownIdentifierWrongPassword).toEqual(unknownIdentifier)
|
|
204
|
-
expect(unknownIdentifier).toEqual({
|
|
205
|
-
status: 400,
|
|
206
|
-
body: {
|
|
207
|
-
error: 'invalid_request',
|
|
208
|
-
error_description: 'Invalid identifier or password',
|
|
209
|
-
},
|
|
210
|
-
})
|
|
211
|
-
})
|
|
212
|
-
|
|
213
|
-
it('provides valid access and refresh token on session refresh.', async () => {
|
|
214
|
-
const email = 'carol@test.com'
|
|
215
|
-
const account = await createAccount({
|
|
216
|
-
handle: 'carol.test',
|
|
217
|
-
password: 'password',
|
|
218
|
-
email,
|
|
219
|
-
})
|
|
220
|
-
const session = await refreshSession(account.refreshJwt)
|
|
221
|
-
// Valid access token
|
|
222
|
-
const sessionInfo = await getSession(session.accessJwt)
|
|
223
|
-
expect(sessionInfo).toEqual({
|
|
224
|
-
did: session.did,
|
|
225
|
-
handle: session.handle,
|
|
226
|
-
email,
|
|
227
|
-
emailConfirmed: false,
|
|
228
|
-
active: true,
|
|
229
|
-
})
|
|
230
|
-
// Valid refresh token
|
|
231
|
-
const nextSession = await refreshSession(session.refreshJwt)
|
|
232
|
-
expect(nextSession).toEqual(
|
|
233
|
-
expect.objectContaining({
|
|
234
|
-
did: session.did,
|
|
235
|
-
handle: session.handle,
|
|
236
|
-
}),
|
|
237
|
-
)
|
|
238
|
-
})
|
|
239
|
-
|
|
240
|
-
it('handles racing refreshes', async () => {
|
|
241
|
-
const email = 'dan@test.com'
|
|
242
|
-
const account = await createAccount({
|
|
243
|
-
handle: 'dan.test',
|
|
244
|
-
password: 'password',
|
|
245
|
-
email,
|
|
246
|
-
})
|
|
247
|
-
const tokenIdPromises: Promise<string>[] = []
|
|
248
|
-
const doRefresh = async () => {
|
|
249
|
-
const res = await refreshSession(account.refreshJwt)
|
|
250
|
-
const decoded = jose.decodeJwt(res.refreshJwt)
|
|
251
|
-
if (!decoded?.jti) {
|
|
252
|
-
throw new Error('undefined jti on refresh token')
|
|
253
|
-
}
|
|
254
|
-
return decoded.jti
|
|
255
|
-
}
|
|
256
|
-
for (let i = 0; i < 10; i++) {
|
|
257
|
-
tokenIdPromises.push(doRefresh())
|
|
258
|
-
}
|
|
259
|
-
const tokenIds = await Promise.all(tokenIdPromises)
|
|
260
|
-
for (let i = 0; i < 10; i++) {
|
|
261
|
-
expect(tokenIds[i]).toEqual(tokenIds[0])
|
|
262
|
-
}
|
|
263
|
-
})
|
|
264
|
-
|
|
265
|
-
it('refresh token provides new token with same id on multiple uses during grace period.', async () => {
|
|
266
|
-
const account = await createAccount({
|
|
267
|
-
handle: 'eve.test',
|
|
268
|
-
email: 'eve@test.com',
|
|
269
|
-
password: 'password',
|
|
270
|
-
})
|
|
271
|
-
const refresh1 = await refreshSession(account.refreshJwt)
|
|
272
|
-
const refresh2 = await refreshSession(account.refreshJwt)
|
|
273
|
-
|
|
274
|
-
const token0 = jose.decodeJwt(account.refreshJwt)
|
|
275
|
-
const token1 = jose.decodeJwt(refresh1.refreshJwt)
|
|
276
|
-
const token2 = jose.decodeJwt(refresh2.refreshJwt)
|
|
277
|
-
|
|
278
|
-
expect(typeof token1?.jti).toEqual('string')
|
|
279
|
-
expect(token1?.jti).toEqual(token2?.jti)
|
|
280
|
-
expect(token1?.jti).not.toEqual(token0?.jti)
|
|
281
|
-
expect(token2?.jti).not.toEqual(token0?.jti)
|
|
282
|
-
})
|
|
283
|
-
|
|
284
|
-
it('refresh token is revoked after grace period completes.', async () => {
|
|
285
|
-
const { db } = network.pds.ctx.accountManager
|
|
286
|
-
const account = await createAccount({
|
|
287
|
-
handle: 'evan.test',
|
|
288
|
-
email: 'evan@test.com',
|
|
289
|
-
password: 'password',
|
|
290
|
-
})
|
|
291
|
-
await refreshSession(account.refreshJwt)
|
|
292
|
-
const token = jose.decodeJwt(account.refreshJwt)
|
|
293
|
-
|
|
294
|
-
// Update expiration (i.e. grace period) to end immediately
|
|
295
|
-
const refreshUpdated = await db.db
|
|
296
|
-
.updateTable('refresh_token')
|
|
297
|
-
.set({ expiresAt: new Date().toISOString() })
|
|
298
|
-
.where('id', '=', token?.jti ?? '')
|
|
299
|
-
.executeTakeFirst()
|
|
300
|
-
expect(Number(refreshUpdated.numUpdatedRows)).toEqual(1)
|
|
301
|
-
|
|
302
|
-
// Token can no longer be used
|
|
303
|
-
const refreshAgain = refreshSession(account.refreshJwt)
|
|
304
|
-
await expect(refreshAgain).rejects.toThrow('Token has been revoked')
|
|
305
|
-
|
|
306
|
-
// Ensure that token was cleaned-up
|
|
307
|
-
const refreshInfo = await db.db
|
|
308
|
-
.selectFrom('refresh_token')
|
|
309
|
-
.selectAll()
|
|
310
|
-
.where('id', '=', token?.jti ?? '')
|
|
311
|
-
.executeTakeFirst()
|
|
312
|
-
expect(refreshInfo).toBeUndefined()
|
|
313
|
-
})
|
|
314
|
-
|
|
315
|
-
it('refresh token is revoked when session is deleted.', async () => {
|
|
316
|
-
const account = await createAccount({
|
|
317
|
-
handle: 'finn.test',
|
|
318
|
-
email: 'finn@test.com',
|
|
319
|
-
password: 'password',
|
|
320
|
-
})
|
|
321
|
-
await deleteSession(account.refreshJwt)
|
|
322
|
-
const refreshDeleted = refreshSession(account.refreshJwt)
|
|
323
|
-
await expect(refreshDeleted).rejects.toThrow('Token has been revoked')
|
|
324
|
-
await deleteSession(account.refreshJwt) // No problem double-revoking a token
|
|
325
|
-
})
|
|
326
|
-
|
|
327
|
-
it('access token cannot be used to refresh a session.', async () => {
|
|
328
|
-
const account = await createAccount({
|
|
329
|
-
handle: 'gordon.test',
|
|
330
|
-
email: 'gordon@test.com',
|
|
331
|
-
password: 'password',
|
|
332
|
-
})
|
|
333
|
-
const refreshWithAccess = refreshSession(account.accessJwt)
|
|
334
|
-
await expect(refreshWithAccess).rejects.toThrow(
|
|
335
|
-
'Token could not be verified',
|
|
336
|
-
)
|
|
337
|
-
})
|
|
338
|
-
|
|
339
|
-
it('expired refresh token cannot be used to refresh a session.', async () => {
|
|
340
|
-
const account = await createAccount({
|
|
341
|
-
handle: 'holga.test',
|
|
342
|
-
email: 'holga@test.com',
|
|
343
|
-
password: 'password',
|
|
344
|
-
})
|
|
345
|
-
const refreshJwt = await createRefreshToken({
|
|
346
|
-
did: account.did,
|
|
347
|
-
jwtKey: network.pds.jwtSecretKey(),
|
|
348
|
-
serviceDid: network.pds.ctx.cfg.service.did,
|
|
349
|
-
expiresIn: -1,
|
|
350
|
-
})
|
|
351
|
-
const refreshExpired = refreshSession(refreshJwt)
|
|
352
|
-
await expect(refreshExpired).rejects.toThrow('Token has expired')
|
|
353
|
-
await deleteSession(refreshJwt) // No problem revoking an expired token
|
|
354
|
-
})
|
|
355
|
-
|
|
356
|
-
it('actor takedown disallows fresh session.', async () => {
|
|
357
|
-
const account = await createAccount({
|
|
358
|
-
handle: 'iris.test',
|
|
359
|
-
email: 'iris@test.com',
|
|
360
|
-
password: 'password',
|
|
361
|
-
})
|
|
362
|
-
await agent.com.atproto.admin.updateSubjectStatus(
|
|
363
|
-
{
|
|
364
|
-
subject: {
|
|
365
|
-
$type: 'com.atproto.admin.defs#repoRef',
|
|
366
|
-
did: account.did,
|
|
367
|
-
},
|
|
368
|
-
takedown: { applied: true },
|
|
369
|
-
},
|
|
370
|
-
{
|
|
371
|
-
encoding: 'application/json',
|
|
372
|
-
headers: { authorization: network.pds.adminAuth() },
|
|
373
|
-
},
|
|
374
|
-
)
|
|
375
|
-
await expect(
|
|
376
|
-
createSession({ identifier: 'iris.test', password: 'password' }),
|
|
377
|
-
).rejects.toMatchObject({
|
|
378
|
-
error: 'AccountTakedown',
|
|
379
|
-
})
|
|
380
|
-
})
|
|
381
|
-
|
|
382
|
-
it('actor takedown disallows refresh session.', async () => {
|
|
383
|
-
const account = await createAccount({
|
|
384
|
-
handle: 'jared.test',
|
|
385
|
-
email: 'jared@test.com',
|
|
386
|
-
password: 'password',
|
|
387
|
-
})
|
|
388
|
-
await agent.com.atproto.admin.updateSubjectStatus(
|
|
389
|
-
{
|
|
390
|
-
subject: {
|
|
391
|
-
$type: 'com.atproto.admin.defs#repoRef',
|
|
392
|
-
did: account.did,
|
|
393
|
-
},
|
|
394
|
-
takedown: { applied: true },
|
|
395
|
-
},
|
|
396
|
-
{
|
|
397
|
-
encoding: 'application/json',
|
|
398
|
-
headers: { authorization: network.pds.adminAuth() },
|
|
399
|
-
},
|
|
400
|
-
)
|
|
401
|
-
await expect(refreshSession(account.refreshJwt)).rejects.toMatchObject({
|
|
402
|
-
error: 'AccountTakedown',
|
|
403
|
-
})
|
|
404
|
-
})
|
|
405
|
-
})
|