@atproto/xrpc-server 0.4.4-next.0 → 0.4.4
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 +4 -6
- package/babel.config.js +1 -0
- package/build.js +14 -0
- package/dist/auth.d.ts +1 -2
- package/dist/index.d.ts +0 -1
- package/dist/index.js +53682 -25
- package/dist/index.js.map +7 -1
- package/dist/logger.d.ts +0 -1
- package/dist/rate-limiter.d.ts +0 -1
- package/dist/server.d.ts +4 -5
- package/dist/stream/frames.d.ts +1 -2
- package/dist/stream/index.d.ts +0 -1
- package/dist/stream/logger.d.ts +0 -1
- package/dist/stream/server.d.ts +0 -2
- package/dist/stream/stream.d.ts +0 -1
- package/dist/stream/subscription.d.ts +0 -2
- package/dist/stream/types.d.ts +0 -1
- package/dist/stream/websocket-keepalive.d.ts +0 -2
- package/dist/types.d.ts +0 -2
- package/dist/util.d.ts +0 -1
- package/jest.config.js +3 -4
- package/package.json +11 -10
- package/src/auth.ts +1 -1
- package/src/server.ts +11 -11
- package/src/stream/frames.ts +1 -1
- package/src/stream/websocket-keepalive.ts +1 -2
- package/tests/bodies.test.ts +4 -4
- package/tests/errors.test.ts +1 -1
- package/tsconfig.build.json +2 -6
- package/tsconfig.json +11 -3
- package/dist/auth.d.ts.map +0 -1
- package/dist/auth.js +0 -124
- package/dist/auth.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/logger.d.ts.map +0 -1
- package/dist/logger.js +0 -7
- package/dist/logger.js.map +0 -1
- package/dist/rate-limiter.d.ts.map +0 -1
- package/dist/rate-limiter.js +0 -166
- package/dist/rate-limiter.js.map +0 -1
- package/dist/server.d.ts.map +0 -1
- package/dist/server.js +0 -472
- package/dist/server.js.map +0 -1
- package/dist/stream/frames.d.ts.map +0 -1
- package/dist/stream/frames.js +0 -141
- package/dist/stream/frames.js.map +0 -1
- package/dist/stream/index.d.ts.map +0 -1
- package/dist/stream/index.js +0 -22
- package/dist/stream/index.js.map +0 -1
- package/dist/stream/logger.d.ts.map +0 -1
- package/dist/stream/logger.js +0 -7
- package/dist/stream/logger.js.map +0 -1
- package/dist/stream/server.d.ts.map +0 -1
- package/dist/stream/server.js +0 -70
- package/dist/stream/server.js.map +0 -1
- package/dist/stream/stream.d.ts.map +0 -1
- package/dist/stream/stream.js +0 -44
- package/dist/stream/stream.js.map +0 -1
- package/dist/stream/subscription.d.ts.map +0 -1
- package/dist/stream/subscription.js +0 -80
- package/dist/stream/subscription.js.map +0 -1
- package/dist/stream/types.d.ts.map +0 -1
- package/dist/stream/types.js +0 -47
- package/dist/stream/types.js.map +0 -1
- package/dist/stream/websocket-keepalive.d.ts.map +0 -1
- package/dist/stream/websocket-keepalive.js +0 -160
- package/dist/stream/websocket-keepalive.js.map +0 -1
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -163
- package/dist/types.js.map +0 -1
- package/dist/util.d.ts.map +0 -1
- package/dist/util.js +0 -263
- package/dist/util.js.map +0 -1
- package/tsconfig.tests.json +0 -7
package/dist/logger.d.ts
CHANGED
package/dist/rate-limiter.d.ts
CHANGED
|
@@ -29,4 +29,3 @@ export declare const formatLimiterStatus: (limiter: RateLimiterAbstract, res: Ra
|
|
|
29
29
|
export declare const consumeMany: (ctx: XRPCReqContext, fns: RateLimiterConsume[]) => Promise<RateLimiterStatus | RateLimitExceededError | null>;
|
|
30
30
|
export declare const setResHeaders: (ctx: XRPCReqContext, status: RateLimiterStatus) => void;
|
|
31
31
|
export declare const getTightestLimit: (resps: (RateLimiterStatus | RateLimitExceededError | null)[]) => RateLimiterStatus | RateLimitExceededError | null;
|
|
32
|
-
//# sourceMappingURL=rate-limiter.d.ts.map
|
package/dist/server.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import
|
|
1
|
+
import express, { NextFunction, RequestHandler } from 'express';
|
|
2
2
|
import { LexiconDoc, Lexicons, LexXrpcProcedure, LexXrpcQuery, LexXrpcSubscription } from '@atproto/lexicon';
|
|
3
3
|
import { XrpcStreamServer } from './stream';
|
|
4
4
|
import { XRPCHandler, XRPCHandlerConfig, Options, XRPCStreamHandlerConfig, XRPCStreamHandler, RateLimiterI, RateLimiterConsume } from './types';
|
|
5
5
|
export declare function createServer(lexicons?: LexiconDoc[], options?: Options): Server;
|
|
6
6
|
export declare class Server {
|
|
7
|
-
router: Express;
|
|
8
|
-
routes: Router;
|
|
7
|
+
router: import("express-serve-static-core").Express;
|
|
8
|
+
routes: import("express-serve-static-core").Router;
|
|
9
9
|
subscriptions: Map<string, XrpcStreamServer>;
|
|
10
10
|
lex: Lexicons;
|
|
11
11
|
options: Options;
|
|
@@ -21,10 +21,9 @@ export declare class Server {
|
|
|
21
21
|
addLexicon(doc: LexiconDoc): void;
|
|
22
22
|
addLexicons(docs: LexiconDoc[]): void;
|
|
23
23
|
protected addRoute(nsid: string, def: LexXrpcQuery | LexXrpcProcedure, config: XRPCHandlerConfig): Promise<void>;
|
|
24
|
-
catchall(req: Request, _res: Response, next: NextFunction): Promise<void>;
|
|
24
|
+
catchall(req: express.Request, _res: express.Response, next: NextFunction): Promise<void>;
|
|
25
25
|
createHandler(nsid: string, def: LexXrpcQuery | LexXrpcProcedure, routeCfg: XRPCHandlerConfig): RequestHandler;
|
|
26
26
|
protected addSubscription(nsid: string, def: LexXrpcSubscription, config: XRPCStreamHandlerConfig): Promise<void>;
|
|
27
27
|
private enableStreamingOnListen;
|
|
28
28
|
private setupRouteRateLimits;
|
|
29
29
|
}
|
|
30
|
-
//# sourceMappingURL=server.d.ts.map
|
package/dist/stream/frames.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { FrameHeader, FrameType, MessageFrameHeader, ErrorFrameHeader, ErrorFrameBody } from './types';
|
|
2
2
|
export declare abstract class Frame {
|
|
3
|
-
|
|
3
|
+
header: FrameHeader;
|
|
4
4
|
body: unknown;
|
|
5
5
|
get op(): FrameType;
|
|
6
6
|
toBytes(): Uint8Array;
|
|
@@ -23,4 +23,3 @@ export declare class ErrorFrame<T extends string = string> extends Frame {
|
|
|
23
23
|
get code(): T & string;
|
|
24
24
|
get message(): string | undefined;
|
|
25
25
|
}
|
|
26
|
-
//# sourceMappingURL=frames.d.ts.map
|
package/dist/stream/index.d.ts
CHANGED
package/dist/stream/logger.d.ts
CHANGED
package/dist/stream/server.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
|
-
/// <reference types="node" />
|
|
3
2
|
import { IncomingMessage } from 'http';
|
|
4
3
|
import { WebSocketServer, ServerOptions, WebSocket } from 'ws';
|
|
5
4
|
import { Frame } from './frames';
|
|
@@ -10,4 +9,3 @@ export declare class XrpcStreamServer {
|
|
|
10
9
|
});
|
|
11
10
|
}
|
|
12
11
|
export type Handler = (req: IncomingMessage, signal: AbortSignal, socket: WebSocket, server: XrpcStreamServer) => AsyncIterable<Frame>;
|
|
13
|
-
//# sourceMappingURL=server.d.ts.map
|
package/dist/stream/stream.d.ts
CHANGED
|
@@ -6,4 +6,3 @@ export declare function streamByteChunks(ws: WebSocket, options?: DuplexOptions)
|
|
|
6
6
|
export declare function byFrame(ws: WebSocket, options?: DuplexOptions): AsyncGenerator<MessageFrame<unknown> | import("./frames").ErrorFrame<string>, void, unknown>;
|
|
7
7
|
export declare function byMessage(ws: WebSocket, options?: DuplexOptions): AsyncGenerator<MessageFrame<unknown>, void, unknown>;
|
|
8
8
|
export declare function ensureChunkIsMessage(chunk: Uint8Array): MessageFrame<unknown>;
|
|
9
|
-
//# sourceMappingURL=stream.d.ts.map
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/// <reference types="node" />
|
|
2
1
|
import { ClientOptions } from 'ws';
|
|
3
2
|
export declare class Subscription<T = unknown> {
|
|
4
3
|
opts: ClientOptions & {
|
|
@@ -24,4 +23,3 @@ export declare class Subscription<T = unknown> {
|
|
|
24
23
|
[Symbol.asyncIterator](): AsyncGenerator<T>;
|
|
25
24
|
}
|
|
26
25
|
export default Subscription;
|
|
27
|
-
//# sourceMappingURL=subscription.d.ts.map
|
package/dist/stream/types.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/// <reference types="node" />
|
|
2
1
|
import { WebSocket, ClientOptions } from 'ws';
|
|
3
2
|
export declare class WebSocketKeepAlive {
|
|
4
3
|
opts: ClientOptions & {
|
|
@@ -22,4 +21,3 @@ export declare class WebSocketKeepAlive {
|
|
|
22
21
|
startHeartbeat(ws: WebSocket): void;
|
|
23
22
|
}
|
|
24
23
|
export default WebSocketKeepAlive;
|
|
25
|
-
//# sourceMappingURL=websocket-keepalive.d.ts.map
|
package/dist/types.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
|
-
/// <reference types="node" />
|
|
3
2
|
import { IncomingMessage } from 'http';
|
|
4
3
|
import express from 'express';
|
|
5
4
|
import zod from 'zod';
|
|
@@ -206,4 +205,3 @@ export declare class UpstreamTimeoutError extends XRPCError {
|
|
|
206
205
|
export declare class MethodNotImplementedError extends XRPCError {
|
|
207
206
|
constructor(errorMessage?: string, customErrorName?: string);
|
|
208
207
|
}
|
|
209
|
-
//# sourceMappingURL=types.d.ts.map
|
package/dist/util.d.ts
CHANGED
package/jest.config.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
const base = require('../../jest.config.base.js')
|
|
2
|
+
|
|
2
3
|
module.exports = {
|
|
4
|
+
...base,
|
|
3
5
|
displayName: 'XRPC Server',
|
|
4
|
-
transform: { '^.+\\.(t|j)s$': '@swc/jest' },
|
|
5
|
-
transformIgnorePatterns: [`<rootDir>/node_modules/(?!get-port)`],
|
|
6
|
-
setupFiles: ['<rootDir>/../../jest.setup.ts'],
|
|
7
6
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atproto/xrpc-server",
|
|
3
|
-
"version": "0.4.4
|
|
3
|
+
"version": "0.4.4",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "atproto HTTP API (XRPC) server library",
|
|
6
6
|
"keywords": [
|
|
@@ -14,7 +14,6 @@
|
|
|
14
14
|
"directory": "packages/xrpc-server"
|
|
15
15
|
},
|
|
16
16
|
"main": "dist/index.js",
|
|
17
|
-
"types": "dist/index.d.ts",
|
|
18
17
|
"dependencies": {
|
|
19
18
|
"cbor-x": "^1.5.1",
|
|
20
19
|
"express": "^4.17.2",
|
|
@@ -24,9 +23,9 @@
|
|
|
24
23
|
"uint8arrays": "3.0.0",
|
|
25
24
|
"ws": "^8.12.0",
|
|
26
25
|
"zod": "^3.21.4",
|
|
27
|
-
"@atproto/common": "^0.3.4
|
|
28
|
-
"@atproto/
|
|
29
|
-
"@atproto/
|
|
26
|
+
"@atproto/common": "^0.3.4",
|
|
27
|
+
"@atproto/crypto": "^0.3.0",
|
|
28
|
+
"@atproto/lexicon": "^0.3.3"
|
|
30
29
|
},
|
|
31
30
|
"devDependencies": {
|
|
32
31
|
"@types/express": "^4.17.13",
|
|
@@ -35,14 +34,16 @@
|
|
|
35
34
|
"@types/ws": "^8.5.4",
|
|
36
35
|
"get-port": "^6.1.2",
|
|
37
36
|
"jose": "^4.15.4",
|
|
38
|
-
"jest": "^28.1.2",
|
|
39
37
|
"key-encoder": "^2.0.3",
|
|
40
38
|
"multiformats": "^9.9.0",
|
|
41
|
-
"@atproto/crypto": "^0.3.
|
|
42
|
-
"@atproto/xrpc": "^0.4.3
|
|
39
|
+
"@atproto/crypto": "^0.3.0",
|
|
40
|
+
"@atproto/xrpc": "^0.4.3"
|
|
43
41
|
},
|
|
44
42
|
"scripts": {
|
|
45
43
|
"test": "jest",
|
|
46
|
-
"build": "
|
|
47
|
-
|
|
44
|
+
"build": "node ./build.js",
|
|
45
|
+
"postbuild": "tsc --build tsconfig.build.json",
|
|
46
|
+
"update-main-to-dist": "node ../../update-main-to-dist.js packages/xrpc-server"
|
|
47
|
+
},
|
|
48
|
+
"types": "dist/index.d.ts"
|
|
48
49
|
}
|
package/src/auth.ts
CHANGED
|
@@ -48,7 +48,7 @@ const jsonToB64Url = (json: Record<string, unknown>): string => {
|
|
|
48
48
|
export const verifyJwt = async (
|
|
49
49
|
jwtStr: string,
|
|
50
50
|
ownDid: string | null, // null indicates to skip the audience check
|
|
51
|
-
getSigningKey: (
|
|
51
|
+
getSigningKey: (iss: string, forceRefresh: boolean) => Promise<string>,
|
|
52
52
|
): Promise<ServiceJwtPayload> => {
|
|
53
53
|
const parts = jwtStr.split('.')
|
|
54
54
|
if (parts.length !== 3) {
|
package/src/server.ts
CHANGED
|
@@ -1,10 +1,5 @@
|
|
|
1
1
|
import { Readable } from 'stream'
|
|
2
2
|
import express, {
|
|
3
|
-
Application,
|
|
4
|
-
Express,
|
|
5
|
-
Router,
|
|
6
|
-
Request,
|
|
7
|
-
Response,
|
|
8
3
|
ErrorRequestHandler,
|
|
9
4
|
NextFunction,
|
|
10
5
|
RequestHandler,
|
|
@@ -42,6 +37,7 @@ import {
|
|
|
42
37
|
isShared,
|
|
43
38
|
RateLimitExceededError,
|
|
44
39
|
HandlerPipeThrough,
|
|
40
|
+
handlerPipeThrough,
|
|
45
41
|
} from './types'
|
|
46
42
|
import {
|
|
47
43
|
decodeQueryParams,
|
|
@@ -57,8 +53,8 @@ export function createServer(lexicons?: LexiconDoc[], options?: Options) {
|
|
|
57
53
|
}
|
|
58
54
|
|
|
59
55
|
export class Server {
|
|
60
|
-
router
|
|
61
|
-
routes
|
|
56
|
+
router = express()
|
|
57
|
+
routes = express.Router()
|
|
62
58
|
subscriptions = new Map<string, XrpcStreamServer>()
|
|
63
59
|
lex = new Lexicons()
|
|
64
60
|
options: Options
|
|
@@ -74,7 +70,7 @@ export class Server {
|
|
|
74
70
|
this.router.use(this.routes)
|
|
75
71
|
this.router.use('/xrpc/:methodId', this.catchall.bind(this))
|
|
76
72
|
this.router.use(errorMiddleware)
|
|
77
|
-
this.router.once('mount', (app: Application) => {
|
|
73
|
+
this.router.once('mount', (app: express.Application) => {
|
|
78
74
|
this.enableStreamingOnListen(app)
|
|
79
75
|
})
|
|
80
76
|
this.options = opts ?? {}
|
|
@@ -183,7 +179,11 @@ export class Server {
|
|
|
183
179
|
)
|
|
184
180
|
}
|
|
185
181
|
|
|
186
|
-
async catchall(
|
|
182
|
+
async catchall(
|
|
183
|
+
req: express.Request,
|
|
184
|
+
_res: express.Response,
|
|
185
|
+
next: NextFunction,
|
|
186
|
+
) {
|
|
187
187
|
const def = this.lex.getDef(req.params.methodId)
|
|
188
188
|
if (!def) {
|
|
189
189
|
return next(new MethodNotImplementedError())
|
|
@@ -213,7 +213,7 @@ export class Server {
|
|
|
213
213
|
const routeOpts = {
|
|
214
214
|
blobLimit: routeCfg.opts?.blobLimit ?? this.options.payload?.blobLimit,
|
|
215
215
|
}
|
|
216
|
-
const validateReqInput = (req: Request) =>
|
|
216
|
+
const validateReqInput = (req: express.Request) =>
|
|
217
217
|
validateInput(nsid, def, req, routeOpts, this.lex)
|
|
218
218
|
const validateResOutput =
|
|
219
219
|
this.options.validateResponse === false
|
|
@@ -390,7 +390,7 @@ export class Server {
|
|
|
390
390
|
)
|
|
391
391
|
}
|
|
392
392
|
|
|
393
|
-
private enableStreamingOnListen(app: Application) {
|
|
393
|
+
private enableStreamingOnListen(app: express.Application) {
|
|
394
394
|
const _listen = app.listen
|
|
395
395
|
app.listen = (...args) => {
|
|
396
396
|
// @ts-ignore the args spread
|
package/src/stream/frames.ts
CHANGED
|
@@ -80,7 +80,7 @@ export class WebSocketKeepAlive {
|
|
|
80
80
|
|
|
81
81
|
startHeartbeat(ws: WebSocket) {
|
|
82
82
|
let isAlive = true
|
|
83
|
-
let heartbeatInterval: NodeJS.
|
|
83
|
+
let heartbeatInterval: NodeJS.Timer | null = null
|
|
84
84
|
|
|
85
85
|
const checkAlive = () => {
|
|
86
86
|
if (!isAlive) {
|
|
@@ -145,7 +145,6 @@ function forwardSignal(signal: AbortSignal, ac: AbortController) {
|
|
|
145
145
|
return ac.abort(signal.reason)
|
|
146
146
|
} else {
|
|
147
147
|
signal.addEventListener('abort', () => ac.abort(signal.reason), {
|
|
148
|
-
// @ts-ignore https://github.com/DefinitelyTyped/DefinitelyTyped/pull/68625
|
|
149
148
|
signal: ac.signal,
|
|
150
149
|
})
|
|
151
150
|
}
|
package/tests/bodies.test.ts
CHANGED
|
@@ -274,9 +274,9 @@ describe('Bodies', () => {
|
|
|
274
274
|
const resBody = await res.json()
|
|
275
275
|
const status = res.status
|
|
276
276
|
expect(status).toBe(400)
|
|
277
|
-
expect(resBody).
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
277
|
+
expect(resBody.error).toBe('InvalidRequest')
|
|
278
|
+
expect(resBody.message).toBe(
|
|
279
|
+
'Request encoding (Content-Type) required but not provided',
|
|
280
|
+
)
|
|
281
281
|
})
|
|
282
282
|
})
|
package/tests/errors.test.ts
CHANGED
package/tsconfig.build.json
CHANGED
package/tsconfig.json
CHANGED
|
@@ -1,7 +1,15 @@
|
|
|
1
1
|
{
|
|
2
|
-
"
|
|
2
|
+
"extends": "../../tsconfig.json",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"rootDir": "./src",
|
|
5
|
+
"outDir": "./dist", // Your outDir,
|
|
6
|
+
"emitDeclarationOnly": true
|
|
7
|
+
},
|
|
8
|
+
"include": ["./src", "__tests__/**/**.ts"],
|
|
3
9
|
"references": [
|
|
4
|
-
{ "path": "
|
|
5
|
-
{ "path": "
|
|
10
|
+
{ "path": "../common/tsconfig.build.json" },
|
|
11
|
+
{ "path": "../crypto/tsconfig.build.json" },
|
|
12
|
+
{ "path": "../lexicon/tsconfig.build.json" },
|
|
13
|
+
{ "path": "../xrpc/tsconfig.build.json" }
|
|
6
14
|
]
|
|
7
15
|
}
|
package/dist/auth.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,MAAM,iBAAiB,CAAA;AAIzC,KAAK,iBAAiB,GAAG;IACvB,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,CAAC,EAAE,MAAM,CAAA;CACb,CAAA;AAED,KAAK,gBAAgB,GAAG,iBAAiB,GAAG;IAC1C,OAAO,EAAE,MAAM,CAAC,OAAO,CAAA;CACxB,CAAA;AAED,eAAO,MAAM,gBAAgB,WACnB,gBAAgB,KACvB,QAAQ,MAAM,CAgBhB,CAAA;AAED,eAAO,MAAM,wBAAwB,WAAkB,gBAAgB;;;;EAKtE,CAAA;AAMD,eAAO,MAAM,SAAS,WACZ,MAAM,UACN,MAAM,GAAG,IAAI,uBACA,MAAM,gBAAgB,OAAO,KAAK,QAAQ,MAAM,CAAC,KACrE,QAAQ,iBAAiB,CA8D3B,CAAA"}
|
package/dist/auth.js
DELETED
|
@@ -1,124 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
-
if (mod && mod.__esModule) return mod;
|
|
20
|
-
var result = {};
|
|
21
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
-
__setModuleDefault(result, mod);
|
|
23
|
-
return result;
|
|
24
|
-
};
|
|
25
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
-
exports.verifyJwt = exports.createServiceAuthHeaders = exports.createServiceJwt = void 0;
|
|
27
|
-
const common = __importStar(require("@atproto/common"));
|
|
28
|
-
const common_1 = require("@atproto/common");
|
|
29
|
-
const crypto = __importStar(require("@atproto/crypto"));
|
|
30
|
-
const ui8 = __importStar(require("uint8arrays"));
|
|
31
|
-
const types_1 = require("./types");
|
|
32
|
-
const createServiceJwt = async (params) => {
|
|
33
|
-
const { iss, aud, keypair } = params;
|
|
34
|
-
const exp = params.exp ?? Math.floor((Date.now() + common_1.MINUTE) / 1000);
|
|
35
|
-
const header = {
|
|
36
|
-
typ: 'JWT',
|
|
37
|
-
alg: keypair.jwtAlg,
|
|
38
|
-
};
|
|
39
|
-
const payload = {
|
|
40
|
-
iss,
|
|
41
|
-
aud,
|
|
42
|
-
exp,
|
|
43
|
-
};
|
|
44
|
-
const toSignStr = `${jsonToB64Url(header)}.${jsonToB64Url(payload)}`;
|
|
45
|
-
const toSign = ui8.fromString(toSignStr, 'utf8');
|
|
46
|
-
const sig = await keypair.sign(toSign);
|
|
47
|
-
return `${toSignStr}.${ui8.toString(sig, 'base64url')}`;
|
|
48
|
-
};
|
|
49
|
-
exports.createServiceJwt = createServiceJwt;
|
|
50
|
-
const createServiceAuthHeaders = async (params) => {
|
|
51
|
-
const jwt = await (0, exports.createServiceJwt)(params);
|
|
52
|
-
return {
|
|
53
|
-
headers: { authorization: `Bearer ${jwt}` },
|
|
54
|
-
};
|
|
55
|
-
};
|
|
56
|
-
exports.createServiceAuthHeaders = createServiceAuthHeaders;
|
|
57
|
-
const jsonToB64Url = (json) => {
|
|
58
|
-
return common.utf8ToB64Url(JSON.stringify(json));
|
|
59
|
-
};
|
|
60
|
-
const verifyJwt = async (jwtStr, ownDid, // null indicates to skip the audience check
|
|
61
|
-
getSigningKey) => {
|
|
62
|
-
const parts = jwtStr.split('.');
|
|
63
|
-
if (parts.length !== 3) {
|
|
64
|
-
throw new types_1.AuthRequiredError('poorly formatted jwt', 'BadJwt');
|
|
65
|
-
}
|
|
66
|
-
const payload = parsePayload(parts[1]);
|
|
67
|
-
const sig = parts[2];
|
|
68
|
-
if (Date.now() / 1000 > payload.exp) {
|
|
69
|
-
throw new types_1.AuthRequiredError('jwt expired', 'JwtExpired');
|
|
70
|
-
}
|
|
71
|
-
if (ownDid !== null && payload.aud !== ownDid) {
|
|
72
|
-
throw new types_1.AuthRequiredError('jwt audience does not match service did', 'BadJwtAudience');
|
|
73
|
-
}
|
|
74
|
-
const msgBytes = ui8.fromString(parts.slice(0, 2).join('.'), 'utf8');
|
|
75
|
-
const sigBytes = ui8.fromString(sig, 'base64url');
|
|
76
|
-
const verifySignatureWithKey = (key) => {
|
|
77
|
-
return crypto.verifySignature(key, msgBytes, sigBytes, {
|
|
78
|
-
allowMalleableSig: true,
|
|
79
|
-
});
|
|
80
|
-
};
|
|
81
|
-
const signingKey = await getSigningKey(payload.iss, false);
|
|
82
|
-
let validSig;
|
|
83
|
-
try {
|
|
84
|
-
validSig = await verifySignatureWithKey(signingKey);
|
|
85
|
-
}
|
|
86
|
-
catch (err) {
|
|
87
|
-
throw new types_1.AuthRequiredError('could not verify jwt signature', 'BadJwtSignature');
|
|
88
|
-
}
|
|
89
|
-
if (!validSig) {
|
|
90
|
-
// get fresh signing key in case it failed due to a recent rotation
|
|
91
|
-
const freshSigningKey = await getSigningKey(payload.iss, true);
|
|
92
|
-
try {
|
|
93
|
-
validSig =
|
|
94
|
-
freshSigningKey !== signingKey
|
|
95
|
-
? await verifySignatureWithKey(freshSigningKey)
|
|
96
|
-
: false;
|
|
97
|
-
}
|
|
98
|
-
catch (err) {
|
|
99
|
-
throw new types_1.AuthRequiredError('could not verify jwt signature', 'BadJwtSignature');
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
if (!validSig) {
|
|
103
|
-
throw new types_1.AuthRequiredError('jwt signature does not match jwt issuer', 'BadJwtSignature');
|
|
104
|
-
}
|
|
105
|
-
return payload;
|
|
106
|
-
};
|
|
107
|
-
exports.verifyJwt = verifyJwt;
|
|
108
|
-
const parseB64UrlToJson = (b64) => {
|
|
109
|
-
return JSON.parse(common.b64UrlToUtf8(b64));
|
|
110
|
-
};
|
|
111
|
-
const parsePayload = (b64) => {
|
|
112
|
-
const payload = parseB64UrlToJson(b64);
|
|
113
|
-
if (!payload || typeof payload !== 'object') {
|
|
114
|
-
throw new types_1.AuthRequiredError('poorly formatted jwt', 'BadJwt');
|
|
115
|
-
}
|
|
116
|
-
else if (typeof payload.exp !== 'number') {
|
|
117
|
-
throw new types_1.AuthRequiredError('poorly formatted jwt', 'BadJwt');
|
|
118
|
-
}
|
|
119
|
-
else if (typeof payload.iss !== 'string') {
|
|
120
|
-
throw new types_1.AuthRequiredError('poorly formatted jwt', 'BadJwt');
|
|
121
|
-
}
|
|
122
|
-
return payload;
|
|
123
|
-
};
|
|
124
|
-
//# sourceMappingURL=auth.js.map
|
package/dist/auth.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAA;AACvB,cAAc,QAAQ,CAAA;AACtB,cAAc,UAAU,CAAA;AACxB,cAAc,UAAU,CAAA;AACxB,cAAc,gBAAgB,CAAA;AAE9B,YAAY,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAA;AAC1C,OAAO,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAA"}
|
package/dist/logger.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAEjD,eAAO,MAAM,MAAM,EAAE,UAAU,CAAC,OAAO,eAAe,CACtB,CAAA;AAEhC,eAAe,MAAM,CAAA"}
|
package/dist/logger.js
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.logger = void 0;
|
|
4
|
-
const common_1 = require("@atproto/common");
|
|
5
|
-
exports.logger = (0, common_1.subsystemLogger)('xrpc-server');
|
|
6
|
-
exports.default = exports.logger;
|
|
7
|
-
//# sourceMappingURL=logger.js.map
|
package/dist/logger.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":";;;AAAA,4CAAiD;AAEpC,QAAA,MAAM,GACjB,IAAA,wBAAe,EAAC,aAAa,CAAC,CAAA;AAEhC,kBAAe,cAAM,CAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"rate-limiter.d.ts","sourceRoot":"","sources":["../src/rate-limiter.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,EAGnB,cAAc,EACf,MAAM,uBAAuB,CAAA;AAE9B,OAAO,EACL,SAAS,EACT,YAAY,EACZ,sBAAsB,EACtB,kBAAkB,EAClB,YAAY,EACZ,iBAAiB,EACjB,cAAc,EACf,MAAM,SAAS,CAAA;AAEhB,MAAM,MAAM,eAAe,GAAG;IAC5B,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,EAAE,MAAM,CAAA;IAClB,MAAM,EAAE,MAAM,CAAA;IACd,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAA;IACpB,OAAO,CAAC,EAAE,SAAS,CAAA;IACnB,UAAU,CAAC,EAAE,YAAY,CAAA;IACzB,UAAU,CAAC,EAAE,OAAO,CAAA;CACrB,CAAA;AAED,qBAAa,WAAY,YAAW,YAAY;IACvC,OAAO,EAAE,mBAAmB,CAAA;IACnC,OAAO,CAAC,YAAY,CAAC,CAAQ;IAC7B,OAAO,CAAC,SAAS,CAAC,CAAU;IAC5B,OAAO,CAAC,UAAU,CAAC,CAAS;IACrB,OAAO,EAAE,SAAS,CAAA;IAClB,UAAU,EAAE,YAAY,CAAA;gBAEnB,OAAO,EAAE,mBAAmB,EAAE,IAAI,EAAE,eAAe;IAQ/D,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,eAAe,GAAG,WAAW;IASjD,MAAM,CAAC,KAAK,CAAC,WAAW,EAAE,OAAO,EAAE,IAAI,EAAE,eAAe,GAAG,WAAW;IAUhE,OAAO,CACX,GAAG,EAAE,cAAc,EACnB,IAAI,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,SAAS,CAAC;QAAC,UAAU,CAAC,EAAE,YAAY,CAAA;KAAE,GACxD,OAAO,CAAC,iBAAiB,GAAG,sBAAsB,GAAG,IAAI,CAAC;CA6C9D;AAED,eAAO,MAAM,mBAAmB,YACrB,mBAAmB,OACvB,cAAc,KAClB,iBASF,CAAA;AAED,eAAO,MAAM,WAAW,QACjB,cAAc,OACd,kBAAkB,EAAE,KACxB,QAAQ,iBAAiB,GAAG,sBAAsB,GAAG,IAAI,CAa3D,CAAA;AAED,eAAO,MAAM,aAAa,QACnB,cAAc,UACX,iBAAiB,SAS1B,CAAA;AAED,eAAO,MAAM,gBAAgB,UACpB,CAAC,iBAAiB,GAAG,sBAAsB,GAAG,IAAI,CAAC,EAAE,KAC3D,iBAAiB,GAAG,sBAAsB,GAAG,IAU/C,CAAA"}
|