sst 2.11.18 → 2.12.0
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.
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { APIGatewayProxyStructuredResultV2 } from "aws-lambda";
|
|
2
2
|
export declare function LinkAdapter(config: {
|
|
3
3
|
onLink: (link: string, claims: Record<string, any>) => Promise<APIGatewayProxyStructuredResultV2>;
|
|
4
|
-
onError: (error: any) => Promise<APIGatewayProxyStructuredResultV2>;
|
|
5
4
|
}): () => Promise<{
|
|
6
5
|
type: "step";
|
|
7
6
|
properties: APIGatewayProxyStructuredResultV2;
|
|
8
7
|
} | {
|
|
9
8
|
type: "success";
|
|
10
9
|
properties: any;
|
|
10
|
+
} | {
|
|
11
|
+
type: "error";
|
|
12
|
+
properties?: undefined;
|
|
11
13
|
}>;
|
|
@@ -2,16 +2,16 @@ import { createSigner, createVerifier } from "fast-jwt";
|
|
|
2
2
|
import { Config } from "../../../config/index.js";
|
|
3
3
|
import { useDomainName, usePathParam, useQueryParam, useQueryParams, } from "../../../api/index.js";
|
|
4
4
|
export function LinkAdapter(config) {
|
|
5
|
-
// @ts-expect-error
|
|
6
|
-
const key = Config[process.env.AUTH_ID + "PrivateKey"];
|
|
7
|
-
// @ts-expect-error
|
|
8
|
-
const publicKey = Config[process.env.AUTH_ID + "PublicKey"];
|
|
9
|
-
const signer = createSigner({
|
|
10
|
-
expiresIn: 1000 * 60 * 10,
|
|
11
|
-
key,
|
|
12
|
-
algorithm: "RS512",
|
|
13
|
-
});
|
|
14
5
|
return async function () {
|
|
6
|
+
// @ts-expect-error
|
|
7
|
+
const key = Config[process.env.AUTH_ID + "PrivateKey"];
|
|
8
|
+
// @ts-expect-error
|
|
9
|
+
const publicKey = Config[process.env.AUTH_ID + "PublicKey"];
|
|
10
|
+
const signer = createSigner({
|
|
11
|
+
expiresIn: 1000 * 60 * 10,
|
|
12
|
+
key,
|
|
13
|
+
algorithm: "RS512",
|
|
14
|
+
});
|
|
15
15
|
const callback = "https://" + useDomainName() + "/callback";
|
|
16
16
|
const step = usePathParam("step");
|
|
17
17
|
if (step === "authorize") {
|
|
@@ -38,13 +38,10 @@ export function LinkAdapter(config) {
|
|
|
38
38
|
properties: jwt,
|
|
39
39
|
};
|
|
40
40
|
}
|
|
41
|
-
catch (ex) {
|
|
42
|
-
return {
|
|
43
|
-
type: "step",
|
|
44
|
-
properties: await config.onError(ex),
|
|
45
|
-
};
|
|
46
|
-
}
|
|
41
|
+
catch (ex) { }
|
|
47
42
|
}
|
|
48
|
-
|
|
43
|
+
return {
|
|
44
|
+
type: "error",
|
|
45
|
+
};
|
|
49
46
|
};
|
|
50
47
|
}
|
|
@@ -2,6 +2,25 @@ import { APIGatewayProxyEventV2, APIGatewayProxyStructuredResultV2 } from "aws-l
|
|
|
2
2
|
import { Adapter } from "./adapter/adapter.js";
|
|
3
3
|
import { SignerOptions } from "fast-jwt";
|
|
4
4
|
import { SessionValue } from "./session.js";
|
|
5
|
+
declare const onSuccessResponse: {
|
|
6
|
+
session(input: SessionCreateInput): {
|
|
7
|
+
type: "session";
|
|
8
|
+
properties: SessionCreateInput;
|
|
9
|
+
};
|
|
10
|
+
http(input: APIGatewayProxyStructuredResultV2): {
|
|
11
|
+
type: "http";
|
|
12
|
+
properties: APIGatewayProxyStructuredResultV2;
|
|
13
|
+
};
|
|
14
|
+
provider(provider: string): {
|
|
15
|
+
type: "http";
|
|
16
|
+
properties: {
|
|
17
|
+
statusCode: number;
|
|
18
|
+
headers: {
|
|
19
|
+
Location: string;
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
};
|
|
5
24
|
export declare function AuthHandler<Providers extends Record<string, Adapter<any>>, Result = {
|
|
6
25
|
[key in keyof Providers]: {
|
|
7
26
|
provider: key;
|
|
@@ -12,7 +31,8 @@ export declare function AuthHandler<Providers extends Record<string, Adapter<any
|
|
|
12
31
|
providers: Providers;
|
|
13
32
|
clients: () => Promise<Record<string, string>>;
|
|
14
33
|
onAuthorize?: (event: APIGatewayProxyEventV2) => Promise<void | keyof Providers>;
|
|
15
|
-
onSuccess: (input: Result) => Promise<
|
|
34
|
+
onSuccess: (input: Result, response: typeof onSuccessResponse) => Promise<ReturnType<(typeof onSuccessResponse)[keyof typeof onSuccessResponse]>>;
|
|
16
35
|
onError: () => Promise<APIGatewayProxyStructuredResultV2>;
|
|
17
36
|
}): (event: APIGatewayProxyEventV2, context: import("aws-lambda").Context) => Promise<APIGatewayProxyStructuredResultV2>;
|
|
18
37
|
export type SessionCreateInput = SessionValue & Partial<SignerOptions>;
|
|
38
|
+
export {};
|
|
@@ -1,6 +1,37 @@
|
|
|
1
1
|
import { createSigner, createVerifier } from "fast-jwt";
|
|
2
2
|
import { ApiHandler, useCookie, useCookies, useFormValue, usePathParam, useQueryParam, useQueryParams, useResponse, } from "../../api/index.js";
|
|
3
3
|
import { Config } from "../../config/index.js";
|
|
4
|
+
const onSuccessResponse = {
|
|
5
|
+
session(input) {
|
|
6
|
+
return {
|
|
7
|
+
type: "session",
|
|
8
|
+
properties: input,
|
|
9
|
+
};
|
|
10
|
+
},
|
|
11
|
+
http(input) {
|
|
12
|
+
return {
|
|
13
|
+
type: "http",
|
|
14
|
+
properties: input,
|
|
15
|
+
};
|
|
16
|
+
},
|
|
17
|
+
provider(provider) {
|
|
18
|
+
return {
|
|
19
|
+
type: "http",
|
|
20
|
+
properties: {
|
|
21
|
+
statusCode: 302,
|
|
22
|
+
headers: {
|
|
23
|
+
Location: "/authorize?" +
|
|
24
|
+
new URLSearchParams({
|
|
25
|
+
provider,
|
|
26
|
+
response_type: useCookie("response_type"),
|
|
27
|
+
client_id: useCookie("client_id"),
|
|
28
|
+
redirect_uri: useCookie("redirect_uri"),
|
|
29
|
+
}).toString(),
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
},
|
|
34
|
+
};
|
|
4
35
|
export function AuthHandler(input) {
|
|
5
36
|
return ApiHandler(async (evt) => {
|
|
6
37
|
const step = usePathParam("step");
|
|
@@ -13,6 +44,9 @@ export function AuthHandler(input) {
|
|
|
13
44
|
},
|
|
14
45
|
body: `
|
|
15
46
|
<html>
|
|
47
|
+
<head>
|
|
48
|
+
<link rel="icon" href="data:,">
|
|
49
|
+
</head>
|
|
16
50
|
<body>
|
|
17
51
|
<table>
|
|
18
52
|
<tr>${Object.keys(clients).map((client) => `<td>${client}</td>`)}</tr>
|
|
@@ -30,6 +64,11 @@ export function AuthHandler(input) {
|
|
|
30
64
|
`,
|
|
31
65
|
};
|
|
32
66
|
}
|
|
67
|
+
if (step === "favicon.ico") {
|
|
68
|
+
return {
|
|
69
|
+
statusCode: 404,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
33
72
|
if (step === "token") {
|
|
34
73
|
if (useFormValue("grant_type") !== "authorization_code") {
|
|
35
74
|
return {
|
|
@@ -139,70 +178,77 @@ export function AuthHandler(input) {
|
|
|
139
178
|
return result.properties;
|
|
140
179
|
}
|
|
141
180
|
if (result.type === "success") {
|
|
142
|
-
const
|
|
181
|
+
const onSuccess = await input.onSuccess({
|
|
143
182
|
provider,
|
|
144
183
|
...result.properties,
|
|
145
|
-
});
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
const token = signer({
|
|
154
|
-
type,
|
|
155
|
-
properties,
|
|
156
|
-
});
|
|
157
|
-
useResponse().cookie({
|
|
158
|
-
key: "sst_auth_token",
|
|
159
|
-
value: token,
|
|
160
|
-
maxAge: 10 * 365 * 24 * 60 * 60,
|
|
161
|
-
secure: true,
|
|
162
|
-
sameSite: "None",
|
|
163
|
-
httpOnly: true,
|
|
164
|
-
});
|
|
165
|
-
const { client_id, response_type, redirect_uri, state } = {
|
|
166
|
-
...useCookies(),
|
|
167
|
-
...useQueryParams(),
|
|
168
|
-
};
|
|
169
|
-
if (response_type === "token") {
|
|
170
|
-
const location = new URL(redirect_uri);
|
|
171
|
-
location.hash = `access_token=${token}&state=${state || ""}`;
|
|
172
|
-
return {
|
|
173
|
-
statusCode: 302,
|
|
174
|
-
headers: {
|
|
175
|
-
Location: location.href,
|
|
176
|
-
},
|
|
177
|
-
};
|
|
178
|
-
}
|
|
179
|
-
if (response_type === "code") {
|
|
180
|
-
// This allows the code to be reused within a 30 second window
|
|
181
|
-
// The code should be single use but we're making this tradeoff to remain stateless
|
|
182
|
-
// In the future can store this in a dynamo table to ensure single use
|
|
183
|
-
const code = createSigner({
|
|
184
|
-
expiresIn: 1000 * 60 * 5,
|
|
184
|
+
}, onSuccessResponse);
|
|
185
|
+
console.log("onSuccess", onSuccess);
|
|
186
|
+
if (onSuccess.type === "session") {
|
|
187
|
+
const { type, properties, ...rest } = onSuccess.properties;
|
|
188
|
+
// @ts-expect-error
|
|
189
|
+
const priv = Config[process.env.AUTH_ID + "PrivateKey"];
|
|
190
|
+
const signer = createSigner({
|
|
191
|
+
...rest,
|
|
185
192
|
key: priv,
|
|
186
193
|
algorithm: "RS512",
|
|
187
|
-
})({
|
|
188
|
-
client_id,
|
|
189
|
-
redirect_uri,
|
|
190
|
-
token: token,
|
|
191
194
|
});
|
|
192
|
-
const
|
|
193
|
-
|
|
194
|
-
|
|
195
|
+
const token = signer({
|
|
196
|
+
type,
|
|
197
|
+
properties,
|
|
198
|
+
});
|
|
199
|
+
useResponse().cookie({
|
|
200
|
+
key: "sst_auth_token",
|
|
201
|
+
value: token,
|
|
202
|
+
maxAge: 10 * 365 * 24 * 60 * 60,
|
|
203
|
+
secure: true,
|
|
204
|
+
sameSite: "None",
|
|
205
|
+
httpOnly: true,
|
|
206
|
+
});
|
|
207
|
+
const { client_id, response_type, redirect_uri, state } = {
|
|
208
|
+
...useCookies(),
|
|
209
|
+
...useQueryParams(),
|
|
210
|
+
};
|
|
211
|
+
if (response_type === "token") {
|
|
212
|
+
const location = new URL(redirect_uri);
|
|
213
|
+
location.hash = `access_token=${token}&state=${state || ""}`;
|
|
214
|
+
return {
|
|
215
|
+
statusCode: 302,
|
|
216
|
+
headers: {
|
|
217
|
+
Location: location.href,
|
|
218
|
+
},
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
if (response_type === "code") {
|
|
222
|
+
// This allows the code to be reused within a 30 second window
|
|
223
|
+
// The code should be single use but we're making this tradeoff to remain stateless
|
|
224
|
+
// In the future can store this in a dynamo table to ensure single use
|
|
225
|
+
const code = createSigner({
|
|
226
|
+
expiresIn: 1000 * 60 * 5,
|
|
227
|
+
key: priv,
|
|
228
|
+
algorithm: "RS512",
|
|
229
|
+
})({
|
|
230
|
+
client_id,
|
|
231
|
+
redirect_uri,
|
|
232
|
+
token: token,
|
|
233
|
+
});
|
|
234
|
+
const location = new URL(redirect_uri);
|
|
235
|
+
location.searchParams.set("code", code);
|
|
236
|
+
location.searchParams.set("state", state || "");
|
|
237
|
+
return {
|
|
238
|
+
statusCode: 302,
|
|
239
|
+
headers: {
|
|
240
|
+
Location: location.href,
|
|
241
|
+
},
|
|
242
|
+
};
|
|
243
|
+
}
|
|
195
244
|
return {
|
|
196
|
-
statusCode:
|
|
197
|
-
|
|
198
|
-
Location: location.href,
|
|
199
|
-
},
|
|
245
|
+
statusCode: 400,
|
|
246
|
+
body: `Unsupported response_type: ${response_type}`,
|
|
200
247
|
};
|
|
201
248
|
}
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
};
|
|
249
|
+
if (onSuccess.type === "http") {
|
|
250
|
+
return onSuccess.properties;
|
|
251
|
+
}
|
|
206
252
|
}
|
|
207
253
|
if (result.type === "error") {
|
|
208
254
|
return input.onError();
|