sst 2.13.1 → 2.13.3

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.
@@ -0,0 +1,67 @@
1
+ import { useCookie, usePathParam, useQueryParam, useQueryParams, useResponse, } from "../../../api/index.js";
2
+ import { randomBytes } from "crypto";
3
+ import { decrypt, encrypt } from "../encryption.js";
4
+ export function CodeAdapter(config) {
5
+ const length = config.length || 6;
6
+ function generate() {
7
+ const buffer = randomBytes(length);
8
+ const otp = Array.from(buffer)
9
+ .map((byte) => byte % 10)
10
+ .join("");
11
+ return otp;
12
+ }
13
+ return async function () {
14
+ const step = usePathParam("step");
15
+ if (step === "authorize") {
16
+ const code = generate();
17
+ const claims = useQueryParams();
18
+ delete claims["client_id"];
19
+ delete claims["redirect_uri"];
20
+ delete claims["response_type"];
21
+ delete claims["provider"];
22
+ useResponse().cookies({
23
+ sst_code: encrypt(code),
24
+ sst_claims: encrypt(JSON.stringify(claims)),
25
+ }, {
26
+ maxAge: 3600,
27
+ secure: true,
28
+ sameSite: "None",
29
+ httpOnly: true,
30
+ });
31
+ return {
32
+ type: "step",
33
+ properties: await config.onCode(code, claims),
34
+ };
35
+ }
36
+ if (step === "callback") {
37
+ const code = decrypt(useCookie("sst_code"));
38
+ const claims = decrypt(useCookie("sst_claims"));
39
+ if (!code || !claims) {
40
+ return {
41
+ type: "error",
42
+ };
43
+ }
44
+ const compare = useQueryParam("code");
45
+ if (code !== compare) {
46
+ return {
47
+ type: "error",
48
+ };
49
+ }
50
+ useResponse().cookies({
51
+ sst_code: "",
52
+ sst_claims: "",
53
+ }, {
54
+ expires: new Date(1),
55
+ });
56
+ return {
57
+ type: "success",
58
+ properties: {
59
+ claims: JSON.parse(claims),
60
+ },
61
+ };
62
+ }
63
+ return {
64
+ type: "error",
65
+ };
66
+ };
67
+ }
@@ -0,0 +1,2 @@
1
+ export declare function encrypt(data: string): string;
2
+ export declare function decrypt(data: string): string | undefined;
@@ -0,0 +1,30 @@
1
+ import { createCipheriv, createDecipheriv, createHash, randomBytes, } from "crypto";
2
+ import { Config } from "../../config/index.js";
3
+ export function encrypt(data) {
4
+ // @ts-expect-error
5
+ const key = Config[process.env.AUTH_ID + "PrivateKey"];
6
+ const hashed = createHash("sha256").update(key).digest();
7
+ const iv = randomBytes(16); // Generate a random IV (Initialization Vector)
8
+ const cipher = createCipheriv("aes-256-cbc", hashed, iv);
9
+ let encrypted = cipher.update(data, "utf8", "hex");
10
+ encrypted += cipher.final("hex");
11
+ return JSON.stringify({
12
+ i: iv.toString("hex"),
13
+ d: encrypted,
14
+ });
15
+ }
16
+ export function decrypt(data) {
17
+ // @ts-expect-error
18
+ const key = Config[process.env.AUTH_ID + "PrivateKey"];
19
+ const hashed = createHash("sha256").update(key).digest();
20
+ try {
21
+ const parsed = JSON.parse(data);
22
+ const decipher = createDecipheriv("aes-256-cbc", hashed, Buffer.from(parsed.i, "hex"));
23
+ let decrypted = decipher.update(parsed.d, "hex", "utf8");
24
+ decrypted += decipher.final("utf8");
25
+ return decrypted;
26
+ }
27
+ catch {
28
+ return;
29
+ }
30
+ }
@@ -32,7 +32,8 @@ export declare function AuthHandler<Providers extends Record<string, Adapter<any
32
32
  clients: () => Promise<Record<string, string>>;
33
33
  onAuthorize?: (event: APIGatewayProxyEventV2) => Promise<void | keyof Providers>;
34
34
  onSuccess: (input: Result, response: typeof onSuccessResponse) => Promise<ReturnType<(typeof onSuccessResponse)[keyof typeof onSuccessResponse]>>;
35
- onError: () => Promise<APIGatewayProxyStructuredResultV2>;
35
+ onIndex?: (event: APIGatewayProxyEventV2) => Promise<APIGatewayProxyStructuredResultV2>;
36
+ onError?: () => Promise<APIGatewayProxyStructuredResultV2>;
36
37
  }): (event: APIGatewayProxyEventV2, context: import("aws-lambda").Context) => Promise<APIGatewayProxyStructuredResultV2>;
37
38
  export type SessionCreateInput = SessionValue & Partial<SignerOptions>;
38
39
  export {};
@@ -23,9 +23,6 @@ const onSuccessResponse = {
23
23
  Location: "/authorize?" +
24
24
  new URLSearchParams({
25
25
  provider,
26
- response_type: useCookie("response_type"),
27
- client_id: useCookie("client_id"),
28
- redirect_uri: useCookie("redirect_uri"),
29
26
  }).toString(),
30
27
  },
31
28
  },
@@ -36,6 +33,9 @@ export function AuthHandler(input) {
36
33
  return ApiHandler(async (evt) => {
37
34
  const step = usePathParam("step");
38
35
  if (!step) {
36
+ if (input.onIndex) {
37
+ return input.onIndex(evt);
38
+ }
39
39
  const clients = await input.clients();
40
40
  return {
41
41
  statusCode: 200,
@@ -125,7 +125,10 @@ export function AuthHandler(input) {
125
125
  body: "Missing provider",
126
126
  };
127
127
  }
128
- const { response_type, client_id, redirect_uri, state } = useQueryParams();
128
+ const { response_type, client_id, redirect_uri, state } = {
129
+ ...useCookies(),
130
+ ...useQueryParams(),
131
+ };
129
132
  if (!provider) {
130
133
  return {
131
134
  statusCode: 400,
@@ -196,13 +199,20 @@ export function AuthHandler(input) {
196
199
  type,
197
200
  properties,
198
201
  });
199
- useResponse().cookie({
202
+ useResponse()
203
+ .cookie({
200
204
  key: "sst_auth_token",
201
205
  value: token,
202
206
  maxAge: 10 * 365 * 24 * 60 * 60,
203
- secure: true,
204
- sameSite: "None",
205
- httpOnly: true,
207
+ })
208
+ .cookies({
209
+ provider: "",
210
+ response_type: "",
211
+ client_id: "",
212
+ redirect_uri: "",
213
+ state: "",
214
+ }, {
215
+ expires: new Date(1),
206
216
  });
207
217
  const { client_id, response_type, redirect_uri, state } = {
208
218
  ...useCookies(),
@@ -251,7 +261,12 @@ export function AuthHandler(input) {
251
261
  }
252
262
  }
253
263
  if (result.type === "error") {
254
- return input.onError();
264
+ if (input.onError)
265
+ return input.onError();
266
+ return {
267
+ statusCode: 400,
268
+ body: "an error has occured",
269
+ };
255
270
  }
256
271
  });
257
272
  }
@@ -9,7 +9,9 @@ export * from "./adapter/facebook.js";
9
9
  export * from "./adapter/microsoft.js";
10
10
  export * from "./adapter/oauth.js";
11
11
  export * from "./adapter/spotify.js";
12
+ export * from "./adapter/code.js";
12
13
  export type { Adapter } from "./adapter/adapter.js";
13
14
  export * from "./session.js";
14
15
  export * from "./handler.js";
16
+ export * from "./encryption.js";
15
17
  export { Issuer } from "openid-client";
@@ -8,6 +8,8 @@ export * from "./adapter/facebook.js";
8
8
  export * from "./adapter/microsoft.js";
9
9
  export * from "./adapter/oauth.js";
10
10
  export * from "./adapter/spotify.js";
11
+ export * from "./adapter/code.js";
11
12
  export * from "./session.js";
12
13
  export * from "./handler.js";
14
+ export * from "./encryption.js";
13
15
  export { Issuer } from "openid-client";
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "sideEffects": false,
3
3
  "name": "sst",
4
- "version": "2.13.1",
4
+ "version": "2.13.3",
5
5
  "bin": {
6
6
  "sst": "cli/sst.js"
7
7
  },
@@ -178694,6 +178694,7 @@ async function AuthKeys(cfnRequest) {
178694
178694
  new import_client_ssm.PutParameterCommand({
178695
178695
  Name: privatePath,
178696
178696
  Value: privateKey,
178697
+ Overwrite: true,
178697
178698
  Type: "SecureString"
178698
178699
  })
178699
178700
  ),
@@ -178701,6 +178702,7 @@ async function AuthKeys(cfnRequest) {
178701
178702
  new import_client_ssm.PutParameterCommand({
178702
178703
  Name: publicPath,
178703
178704
  Value: publicKey,
178705
+ Overwrite: true,
178704
178706
  Type: "SecureString"
178705
178707
  })
178706
178708
  )