@awsless/awsless 0.0.400 → 0.0.402

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/dist/bin.js CHANGED
@@ -8024,19 +8024,22 @@ var DomainSchema = ResourceIdSchema.describe("The domain id to link your Pubsub
8024
8024
  var PubSubDefaultSchema = z14.record(
8025
8025
  ResourceIdSchema,
8026
8026
  z14.object({
8027
+ auth: FunctionSchema,
8027
8028
  domain: DomainSchema.optional(),
8028
- subDomain: z14.string().optional(),
8029
- auth: z14.union([
8030
- ResourceIdSchema,
8031
- z14.object({
8032
- authorizer: FunctionSchema
8033
- // ttl: AuthorizerTtl.default('1 hour'),
8034
- })
8035
- ]),
8036
- policy: z14.object({
8037
- publish: z14.array(z14.string()).optional(),
8038
- subscribe: z14.array(z14.string()).optional()
8039
- }).optional()
8029
+ subDomain: z14.string().optional()
8030
+ // auth: z.union([
8031
+ // ResourceIdSchema,
8032
+ // z.object({
8033
+ // authorizer: FunctionSchema,
8034
+ // // ttl: AuthorizerTtl.default('1 hour'),
8035
+ // }),
8036
+ // ]),
8037
+ // policy: z
8038
+ // .object({
8039
+ // publish: z.array(z.string()).optional(),
8040
+ // subscribe: z.array(z.string()).optional(),
8041
+ // })
8042
+ // .optional(),
8040
8043
  })
8041
8044
  ).optional().describe("Define the pubsub subscriber in your stack.");
8042
8045
  var PubSubSchema = z14.record(
@@ -12276,10 +12279,7 @@ var pubsubFeature = defineFeature({
12276
12279
  onApp(ctx) {
12277
12280
  for (const [id, props] of Object.entries(ctx.appConfig.defaults.pubsub ?? {})) {
12278
12281
  const group = new Node12(ctx.base, "pubsub", id);
12279
- const functionProps = typeof props.auth === "string" ? { file: "" } : props.auth.authorizer;
12280
- const { lambda } = createLambdaFunction(group, ctx, "pubsub-authorizer", id, functionProps);
12281
- lambda.addEnvironment("PUBSUB_POLICY", JSON.stringify(props.policy));
12282
- lambda.addEnvironment("AWS_ACCOUNT_ID", ctx.accountId);
12282
+ const { lambda } = createLambdaFunction(group, ctx, "pubsub-authorizer", id, props.auth);
12283
12283
  const name = formatGlobalResourceName({
12284
12284
  appName: ctx.app.name,
12285
12285
  resourceType: "pubsub",
@@ -12288,6 +12288,7 @@ var pubsubFeature = defineFeature({
12288
12288
  const authorizer = new aws13.iot.Authorizer(group, "authorizer", {
12289
12289
  name,
12290
12290
  functionArn: lambda.arn
12291
+ // enableSigning: false,
12291
12292
  });
12292
12293
  new aws13.lambda.Permission(group, "permission", {
12293
12294
  functionArn: lambda.arn,
@@ -12324,7 +12325,11 @@ var pubsubFeature = defineFeature({
12324
12325
  ctx.onGlobalPolicy((policy) => {
12325
12326
  policy.addStatement({
12326
12327
  actions: [`iot:Publish`],
12327
- resources: [`arn:aws:iot:${ctx.appConfig.region}:${ctx.accountId}:topic/*`]
12328
+ resources: [
12329
+ //
12330
+ `arn:aws:iot:${ctx.appConfig.region}:${ctx.accountId}:topic/*`,
12331
+ `arn:aws:iot:${ctx.appConfig.region}:${ctx.accountId}:topic/${ctx.app.name}/pubsub/*`
12332
+ ]
12328
12333
  // resources: [`arn:aws:iot:${ctx.appConfig.region}:${ctx.accountId}:topic/${ctx.app.name}/*`],
12329
12334
  });
12330
12335
  });
@@ -566,19 +566,22 @@ var DomainSchema = ResourceIdSchema.describe("The domain id to link your Pubsub
566
566
  var PubSubDefaultSchema = z17.record(
567
567
  ResourceIdSchema,
568
568
  z17.object({
569
+ auth: FunctionSchema,
569
570
  domain: DomainSchema.optional(),
570
- subDomain: z17.string().optional(),
571
- auth: z17.union([
572
- ResourceIdSchema,
573
- z17.object({
574
- authorizer: FunctionSchema
575
- // ttl: AuthorizerTtl.default('1 hour'),
576
- })
577
- ]),
578
- policy: z17.object({
579
- publish: z17.array(z17.string()).optional(),
580
- subscribe: z17.array(z17.string()).optional()
581
- }).optional()
571
+ subDomain: z17.string().optional()
572
+ // auth: z.union([
573
+ // ResourceIdSchema,
574
+ // z.object({
575
+ // authorizer: FunctionSchema,
576
+ // // ttl: AuthorizerTtl.default('1 hour'),
577
+ // }),
578
+ // ]),
579
+ // policy: z
580
+ // .object({
581
+ // publish: z.array(z.string()).optional(),
582
+ // subscribe: z.array(z.string()).optional(),
583
+ // })
584
+ // .optional(),
582
585
  })
583
586
  ).optional().describe("Define the pubsub subscriber in your stack.");
584
587
  var PubSubSchema = z17.record(
package/dist/client.d.ts CHANGED
@@ -61,7 +61,7 @@ type ClientProps = {
61
61
  token?: string;
62
62
  };
63
63
  type ClientPropsProvider = () => Promise<ClientProps> | ClientProps;
64
- declare const createPubSubClient: (props: ClientProps | ClientPropsProvider) => {
64
+ declare const createPubSubClient: (app: string, props: ClientProps | ClientPropsProvider) => {
65
65
  publish(topic: string, event: string, payload: unknown, qos: QoS): Promise<void>;
66
66
  subscribe(topic: string, event: string, callback: MessageCallback): Promise<_awsless_mqtt.Unsubscribe>;
67
67
  connected: boolean;
package/dist/client.js CHANGED
@@ -80,7 +80,7 @@ var createHttpClient = (fetcher) => {
80
80
 
81
81
  // src/lib/client/pubsub.ts
82
82
  import { createClient } from "@awsless/mqtt";
83
- var createPubSubClient = (props) => {
83
+ var createPubSubClient = (app, props) => {
84
84
  const mqtt = createClient(async () => {
85
85
  const config = typeof props === "function" ? await props() : props;
86
86
  return {
@@ -89,13 +89,16 @@ var createPubSubClient = (props) => {
89
89
  password: config.token
90
90
  };
91
91
  });
92
+ const getPubSubTopic = (name) => {
93
+ return `${app}/pubsub/${name}`;
94
+ };
92
95
  return {
93
96
  ...mqtt,
94
97
  publish(topic, event, payload, qos) {
95
- return mqtt.publish(topic, JSON.stringify([event, payload]), qos);
98
+ return mqtt.publish(getPubSubTopic(topic), JSON.stringify([event, payload]), qos);
96
99
  },
97
100
  subscribe(topic, event, callback) {
98
- return mqtt.subscribe(topic, (message) => {
101
+ return mqtt.subscribe(getPubSubTopic(topic), (message) => {
99
102
  const [eventName, payload] = JSON.parse(message.toString("utf8"));
100
103
  if (event === eventName) {
101
104
  callback(payload);
Binary file
package/dist/server.d.ts CHANGED
@@ -1,8 +1,9 @@
1
1
  import { AwsCredentialIdentityProvider } from '@aws-sdk/types';
2
2
  import { Mock } from 'vitest';
3
+ import { Duration, DurationFormat } from '@awsless/duration';
3
4
  import { QoS } from '@awsless/iot';
4
5
  export { QoS } from '@awsless/iot';
5
- import { DurationFormat } from '@awsless/duration';
6
+ import { IoTCustomAuthorizerResult } from 'aws-lambda';
6
7
 
7
8
  declare const regions: readonly ["us-east-2", "us-east-1", "us-west-1", "us-west-2", "af-south-1", "ap-east-1", "ap-south-2", "ap-southeast-3", "ap-southeast-4", "ap-south-1", "ap-northeast-3", "ap-northeast-2", "ap-southeast-1", "ap-southeast-2", "ap-northeast-1", "ca-central-1", "eu-central-1", "eu-west-1", "eu-west-2", "eu-south-1", "eu-west-3", "eu-south-2", "eu-north-1", "eu-central-2", "me-south-1", "me-central-1", "sa-east-1"];
8
9
  type Region = (typeof regions)[number];
@@ -89,6 +90,23 @@ type PublishOptions = {
89
90
  declare const PubSub: {
90
91
  publish(topic: string, event: string, payload: unknown, opts?: PublishOptions): Promise<void>;
91
92
  };
93
+ type PubsubAuthorizerResponse = {
94
+ authorized: boolean;
95
+ principalId?: string;
96
+ publish?: string[];
97
+ subscribe?: string[];
98
+ disconnectAfter?: Duration;
99
+ refreshAfter?: Duration;
100
+ };
101
+ type PubsubAuthorizerEvent = {
102
+ protocolData: {
103
+ mqtt?: {
104
+ password?: string;
105
+ };
106
+ };
107
+ };
108
+ declare const pubsubAuthorizerHandle: (cb: (token: string) => PubsubAuthorizerResponse | Promise<PubsubAuthorizerResponse>) => Promise<(event: PubsubAuthorizerEvent) => Promise<IoTCustomAuthorizerResult>>;
109
+ declare const pubsubAuthorizerResponse: (props: PubsubAuthorizerResponse) => IoTCustomAuthorizerResult;
92
110
 
93
111
  declare const getQueueName: <N extends string, S extends string = "stack">(resourceName: N, stackName?: S) => `app--${S}--queue--${N}`;
94
112
  declare const getQueueUrl: (name: string, stack?: string) => string | undefined;
@@ -137,4 +155,4 @@ declare const Topic: TopicResources;
137
155
  declare const APP: "app";
138
156
  declare const STACK: "stack";
139
157
 
140
- export { APP, Auth, type AuthResources, Cache, type CacheResources, type CommandContext, type CommandHandler, CommandOptions, Config, type ConfigResources, Fn, Function, type FunctionMock, type FunctionMockResponse, type FunctionResources, PubSub, type PublishOptions, Queue, type QueueMock, type QueueMockResponse, type QueueResources, type RpcAuthorizerResponse, STACK, Search, type SearchResources, Store, type StoreResources, Table, type TableResources, Task, type TaskMock, type TaskMockResponse, type TaskResources, Topic, type TopicMock, type TopicMockResponse, type TopicResources, getAuthProps, getCacheProps, getConfigName, getConfigValue, getFunctionName, getPubSubTopic, getQueueName, getQueueUrl, getSearchName, getSearchProps, getSiteBucketName, getStoreName, getTableName, getTaskName, getTopicName, mockFunction, mockPubSub, mockQueue, mockTask, mockTopic, setConfigValue };
158
+ export { APP, Auth, type AuthResources, Cache, type CacheResources, type CommandContext, type CommandHandler, CommandOptions, Config, type ConfigResources, Fn, Function, type FunctionMock, type FunctionMockResponse, type FunctionResources, PubSub, type PublishOptions, Queue, type QueueMock, type QueueMockResponse, type QueueResources, type RpcAuthorizerResponse, STACK, Search, type SearchResources, Store, type StoreResources, Table, type TableResources, Task, type TaskMock, type TaskMockResponse, type TaskResources, Topic, type TopicMock, type TopicMockResponse, type TopicResources, getAuthProps, getCacheProps, getConfigName, getConfigValue, getFunctionName, getPubSubTopic, getQueueName, getQueueUrl, getSearchName, getSearchProps, getSiteBucketName, getStoreName, getTableName, getTaskName, getTopicName, mockFunction, mockPubSub, mockQueue, mockTask, mockTopic, pubsubAuthorizerHandle, pubsubAuthorizerResponse, setConfigValue };
package/dist/server.js CHANGED
@@ -363,6 +363,7 @@ var Config = /* @__PURE__ */ new Proxy(
363
363
  );
364
364
 
365
365
  // src/lib/server/pubsub.ts
366
+ import { hours, toSeconds } from "@awsless/duration";
366
367
  import { publish as publish2, QoS } from "@awsless/iot";
367
368
  var getPubSubTopic = (name) => {
368
369
  return `${APP}/pubsub/${name}`;
@@ -376,6 +377,65 @@ var PubSub = {
376
377
  });
377
378
  }
378
379
  };
380
+ var pubsubAuthorizerHandle = async (cb) => {
381
+ return async (event) => {
382
+ const token = Buffer.from(event.protocolData.mqtt?.password ?? "", "base64").toString();
383
+ const response = await cb(token);
384
+ return pubsubAuthorizerResponse(response);
385
+ };
386
+ };
387
+ var pubsubAuthorizerResponse = (props) => {
388
+ const region = process.env.AWS_REGION;
389
+ const accountId = process.env.AWS_ACCOUNT_ID;
390
+ const prefix = `arn:aws:iot:${region}:${accountId}`;
391
+ const statements = [];
392
+ if (props.publish) {
393
+ statements.push({
394
+ Action: "iot:Publish",
395
+ Effect: "Allow",
396
+ Resource: props.publish.map((topic) => {
397
+ return `${prefix}:topic/${topic}`;
398
+ })
399
+ });
400
+ }
401
+ if (props.subscribe) {
402
+ statements.push(
403
+ {
404
+ Action: "iot:Subscribe",
405
+ Effect: "Allow",
406
+ Resource: props.subscribe.map((topic) => {
407
+ return `${prefix}:topicfilter/${topic}`;
408
+ })
409
+ },
410
+ {
411
+ Action: "iot:Receive",
412
+ Effect: "Allow",
413
+ Resource: props.subscribe.map((topic) => {
414
+ return `${prefix}:topic/${topic}`;
415
+ })
416
+ }
417
+ );
418
+ }
419
+ return {
420
+ isAuthenticated: props.authorized,
421
+ principalId: props.principalId ?? Date.now().toString(),
422
+ disconnectAfterInSeconds: Number(toSeconds(props.disconnectAfter ?? hours(1))),
423
+ refreshAfterInSeconds: Number(toSeconds(props.disconnectAfter ?? hours(1))),
424
+ policyDocuments: [
425
+ {
426
+ Version: "2012-10-17",
427
+ Statement: [
428
+ {
429
+ Action: "iot:Connect",
430
+ Effect: "Allow",
431
+ Resource: `${prefix}:client/\${iot:ClientId}`
432
+ },
433
+ ...statements
434
+ ]
435
+ }
436
+ ]
437
+ };
438
+ };
379
439
 
380
440
  // src/lib/server/search.ts
381
441
  import { define, searchClient } from "@awsless/open-search";
@@ -483,5 +543,7 @@ export {
483
543
  mockQueue,
484
544
  mockTask,
485
545
  mockTopic,
546
+ pubsubAuthorizerHandle,
547
+ pubsubAuthorizerResponse,
486
548
  setConfigValue
487
549
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@awsless/awsless",
3
- "version": "0.0.400",
3
+ "version": "0.0.402",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -28,17 +28,17 @@
28
28
  }
29
29
  },
30
30
  "peerDependencies": {
31
- "@awsless/iot": "^0.0.2",
32
31
  "@awsless/lambda": "^0.0.27",
33
32
  "@awsless/mqtt": "^0.0.2",
34
33
  "@awsless/open-search": "^0.0.15",
34
+ "@awsless/iot": "^0.0.2",
35
35
  "@awsless/redis": "^0.0.13",
36
- "@awsless/s3": "^0.0.18",
37
- "@awsless/sns": "^0.0.7",
38
- "@awsless/validate": "^0.0.16",
36
+ "@awsless/ssm": "^0.0.7",
39
37
  "@awsless/weak-cache": "^0.0.1",
38
+ "@awsless/validate": "^0.0.16",
39
+ "@awsless/s3": "^0.0.18",
40
40
  "@awsless/sqs": "^0.0.7",
41
- "@awsless/ssm": "^0.0.7"
41
+ "@awsless/sns": "^0.0.7"
42
42
  },
43
43
  "dependencies": {
44
44
  "@arcanyx/cidr-slicer": "^0.3.0",
@@ -113,12 +113,12 @@
113
113
  "zod": "^3.21.4",
114
114
  "zod-to-json-schema": "^3.22.3",
115
115
  "@awsless/duration": "^0.0.1",
116
+ "@awsless/size": "^0.0.1",
116
117
  "@awsless/formation": "^0.0.57",
117
- "@awsless/code": "^0.0.10",
118
118
  "@awsless/validate": "^0.0.16",
119
- "@awsless/graphql": "^0.0.9",
119
+ "@awsless/code": "^0.0.10",
120
120
  "@awsless/ts-file-cache": "^0.0.10",
121
- "@awsless/size": "^0.0.1"
121
+ "@awsless/graphql": "^0.0.9"
122
122
  },
123
123
  "devDependencies": {
124
124
  "@node-rs/bcrypt": "^1.10.5"