ts-ag 0.0.1-dev.2 → 1.0.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.
Files changed (122) hide show
  1. package/dist/browser.d.ts +1 -0
  2. package/dist/browser.d.ts.map +1 -1
  3. package/dist/browser.js +1 -0
  4. package/dist/cognito/client.d.ts +6 -0
  5. package/dist/cognito/client.d.ts.map +1 -0
  6. package/dist/cognito/client.js +10 -0
  7. package/dist/cognito/errors.d.ts +95 -0
  8. package/dist/cognito/errors.d.ts.map +1 -0
  9. package/dist/cognito/errors.js +128 -0
  10. package/dist/cognito/index.d.ts +5 -0
  11. package/dist/cognito/index.d.ts.map +1 -0
  12. package/dist/cognito/index.js +4 -0
  13. package/dist/cognito/password.d.ts +53 -0
  14. package/dist/cognito/password.d.ts.map +1 -0
  15. package/dist/cognito/password.js +161 -0
  16. package/dist/cognito/user.d.ts +14 -0
  17. package/dist/cognito/user.d.ts.map +1 -0
  18. package/dist/cognito/user.js +34 -0
  19. package/dist/dynamo/errors.d.ts +9 -0
  20. package/dist/dynamo/errors.d.ts.map +1 -0
  21. package/dist/dynamo/errors.js +7 -0
  22. package/dist/dynamo/index.d.ts +2 -0
  23. package/dist/dynamo/index.d.ts.map +1 -0
  24. package/dist/dynamo/index.js +1 -0
  25. package/dist/index.d.ts +5 -0
  26. package/dist/index.d.ts.map +1 -1
  27. package/dist/index.js +6 -0
  28. package/dist/lambda/authentication.d.ts +2 -0
  29. package/dist/lambda/authentication.d.ts.map +1 -0
  30. package/dist/lambda/authentication.js +1 -0
  31. package/dist/lambda/browser.d.ts +2 -0
  32. package/dist/lambda/browser.d.ts.map +1 -1
  33. package/dist/lambda/browser.js +2 -0
  34. package/dist/lambda/client-types.d.ts +19 -19
  35. package/dist/lambda/client-types.d.ts.map +1 -1
  36. package/dist/lambda/client-types.js +9 -1
  37. package/dist/lambda/client.d.ts.map +1 -1
  38. package/dist/lambda/client.js +7 -2
  39. package/dist/lambda/errors.d.ts +19 -19
  40. package/dist/lambda/errors.d.ts.map +1 -1
  41. package/dist/lambda/errors.js +12 -12
  42. package/dist/lambda/handlerUtils.d.ts +8 -3
  43. package/dist/lambda/handlerUtils.d.ts.map +1 -1
  44. package/dist/lambda/handlerUtils.js +3 -2
  45. package/dist/lambda/index.d.ts +1 -0
  46. package/dist/lambda/index.d.ts.map +1 -1
  47. package/dist/lambda/index.js +2 -0
  48. package/dist/lambda/response.d.ts +48 -95
  49. package/dist/lambda/response.d.ts.map +1 -1
  50. package/dist/lambda/response.js +42 -18
  51. package/dist/lambda/server/authentication.d.ts +10 -0
  52. package/dist/lambda/server/authentication.d.ts.map +1 -0
  53. package/dist/lambda/server/authentication.js +24 -0
  54. package/dist/s3/client.d.ts +6 -0
  55. package/dist/s3/client.d.ts.map +1 -0
  56. package/dist/s3/client.js +7 -0
  57. package/dist/s3/errors.d.ts +7 -0
  58. package/dist/s3/errors.d.ts.map +1 -0
  59. package/dist/s3/errors.js +6 -0
  60. package/dist/s3/index.d.ts +5 -0
  61. package/dist/s3/index.d.ts.map +1 -0
  62. package/dist/s3/index.js +4 -0
  63. package/dist/s3/object.d.ts +17 -0
  64. package/dist/s3/object.d.ts.map +1 -0
  65. package/dist/s3/object.js +32 -0
  66. package/dist/s3/signedUrl.d.ts +3 -0
  67. package/dist/s3/signedUrl.d.ts.map +1 -0
  68. package/dist/s3/signedUrl.js +3 -0
  69. package/dist/scripts/clean.js +30 -59
  70. package/dist/scripts/ts-alias.d.ts +3 -0
  71. package/dist/scripts/ts-alias.d.ts.map +1 -0
  72. package/dist/scripts/ts-alias.js +167 -0
  73. package/dist/ses/errors.d.ts +4 -0
  74. package/dist/ses/errors.d.ts.map +1 -0
  75. package/dist/ses/errors.js +3 -0
  76. package/dist/ses/index.d.ts +2 -0
  77. package/dist/ses/index.d.ts.map +1 -0
  78. package/dist/ses/index.js +1 -0
  79. package/dist/ts-alias.js +0 -0
  80. package/dist/types/deep.d.ts +24 -0
  81. package/dist/types/deep.d.ts.map +1 -0
  82. package/dist/types/deep.js +1 -0
  83. package/dist/types/index.d.ts +3 -0
  84. package/dist/types/index.d.ts.map +1 -0
  85. package/dist/types/index.js +2 -0
  86. package/dist/types/safe.d.ts +2 -0
  87. package/dist/types/safe.d.ts.map +1 -0
  88. package/dist/types/safe.js +1 -0
  89. package/dist/utils/fs.d.ts +2 -1
  90. package/dist/utils/fs.d.ts.map +1 -1
  91. package/dist/utils/fs.js +3 -1
  92. package/package.json +31 -22
  93. package/src/browser.ts +3 -1
  94. package/src/cognito/client.ts +11 -0
  95. package/src/cognito/errors.ts +175 -0
  96. package/src/cognito/index.ts +5 -0
  97. package/src/cognito/password.ts +233 -0
  98. package/src/cognito/user.ts +46 -0
  99. package/src/dynamo/errors.ts +11 -0
  100. package/src/dynamo/index.ts +1 -0
  101. package/src/index.ts +8 -0
  102. package/src/lambda/browser.ts +2 -0
  103. package/src/lambda/client-types.ts +55 -29
  104. package/src/lambda/client.ts +7 -2
  105. package/src/lambda/errors.ts +25 -25
  106. package/src/lambda/handlerUtils.ts +30 -25
  107. package/src/lambda/index.ts +3 -0
  108. package/src/lambda/response.ts +90 -26
  109. package/src/lambda/server/authentication.ts +32 -0
  110. package/src/s3/client.ts +8 -0
  111. package/src/s3/errors.ts +6 -0
  112. package/src/s3/index.ts +6 -0
  113. package/src/s3/object.ts +37 -0
  114. package/src/s3/signedUrl.ts +4 -0
  115. package/src/scripts/clean.ts +34 -68
  116. package/src/ses/errors.ts +3 -0
  117. package/src/ses/index.ts +1 -0
  118. package/src/types/deep.ts +43 -0
  119. package/src/types/index.ts +2 -0
  120. package/src/types/safe.ts +1 -0
  121. package/src/utils/fs.ts +4 -2
  122. /package/src/{ts-alias.ts → scripts/ts-alias.ts} +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"fs.d.ts","sourceRoot":"","sources":["../../src/utils/fs.ts"],"names":[],"mappings":"AAIA;;GAEG;AACH,wBAAsB,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAO/D;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,iBAsBvE"}
1
+ {"version":3,"file":"fs.d.ts","sourceRoot":"","sources":["../../src/utils/fs.ts"],"names":[],"mappings":"AAIA;;GAEG;AACH,wBAAsB,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAO/D;AAED;;;GAGG;AACH,wBAAsB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAuB1F"}
package/dist/utils/fs.js CHANGED
@@ -15,6 +15,7 @@ export async function exists(filePath) {
15
15
  }
16
16
  /**
17
17
  * Writes data to a filepath if it is different
18
+ * @returns true if the file is written to
18
19
  */
19
20
  export async function writeIfDifferent(filePath, newData) {
20
21
  // Ensure the directory exists
@@ -29,10 +30,11 @@ export async function writeIfDifferent(filePath, newData) {
29
30
  // Compare the existing data with the new data
30
31
  if (existingData === newData) {
31
32
  // console.log('File contents are identical. No write needed.');
32
- return;
33
+ return false;
33
34
  }
34
35
  }
35
36
  // Write the new data if it's different or the file doesn't exist
36
37
  await writeFile(filePath, newData, 'utf8');
37
38
  console.log(chalk.green('Writing to'), filePath);
39
+ return true;
38
40
  }
package/package.json CHANGED
@@ -1,44 +1,51 @@
1
1
  {
2
2
  "name": "ts-ag",
3
3
  "description": "Useful TS stuff",
4
- "version": "0.0.1-dev.2",
4
+ "version": "1.0.0",
5
5
  "author": "Alexander Hornung",
6
6
  "bugs": "https://github.com/ageorgeh/ts-ag/issues",
7
7
  "bin": {
8
- "ts-alias": "dist/ts-alias.js",
8
+ "ts-alias": "dist/scripts/ts-alias.js",
9
9
  "clean-dist": "dist/scripts/clean.js"
10
10
  },
11
11
  "dependencies": {
12
+ "@aws-sdk/client-cognito-identity-provider": "3.872.0",
13
+ "@aws-sdk/client-s3": "3.872.0",
14
+ "@aws-sdk/s3-request-presigner": "3.872.0",
15
+ "cookie": "1.0.2",
12
16
  "dequal": "^2.0.3",
13
- "glob": "11.0.2",
17
+ "glob": "11.0.3",
14
18
  "chokidar": "4.0.3",
15
19
  "tsc-alias": "1.8.16",
16
20
  "valibot": "1.1.0",
17
21
  "cycle": "1.0.3",
18
22
  "@ungap/structured-clone": "1.3.0",
19
- "jose": "6.0.11",
23
+ "jose": "6.0.12",
20
24
  "rehype-parse": "9.0.1",
21
- "@types/hast": "3.0.4",
22
25
  "unified": "11.0.5",
23
26
  "vfile": "6.0.3",
24
- "chalk": "5.4.1",
25
- "neverthrow": "8.2.0"
27
+ "chalk": "5.6.0",
28
+ "neverthrow": "8.2.0",
29
+ "tsconfck": "3.1.6",
30
+ "devalue": "5.1.1"
26
31
  },
27
32
  "peerDependencies": {},
28
33
  "devDependencies": {
29
- "jiti": "2.4.2",
30
- "@eslint/js": "^9.26.0",
31
- "eslint": "^9.26.0",
32
- "eslint-plugin-import": "^2.31.0",
33
- "globals": "^16.1.0",
34
- "prettier": "^3.5.3",
35
- "typescript": "^5.8.3",
36
- "typescript-eslint": "^8.32.0",
37
- "typescript-svelte-plugin": "0.3.47",
38
- "npm-check-updates": "^18.0.1",
39
- "@types/node": "^22.15.17",
40
- "@types/aws-lambda": "8.10.149",
41
- "@types/ungap__structured-clone": "1.2.0"
34
+ "jiti": "2.5.1",
35
+ "@eslint/js": "^9.33.0",
36
+ "eslint": "^9.33.0",
37
+ "eslint-plugin-import": "^2.32.0",
38
+ "globals": "^16.3.0",
39
+ "prettier": "^3.6.2",
40
+ "typescript": "^5.9.2",
41
+ "typescript-eslint": "^8.40.0",
42
+ "typescript-svelte-plugin": "0.3.50",
43
+ "npm-check-updates": "^18.0.2",
44
+ "concurrently": "^9.2.0",
45
+ "@types/node": "^24.3.0",
46
+ "@types/aws-lambda": "8.10.152",
47
+ "@types/ungap__structured-clone": "1.2.0",
48
+ "@types/hast": "3.0.4"
42
49
  },
43
50
  "type": "module",
44
51
  "files": [
@@ -61,9 +68,11 @@
61
68
  "repository": "ageorgeh/ts-ag",
62
69
  "scripts": {
63
70
  "tsc:build": "tsc",
64
- "tsc:watch": "tsc --watch",
71
+ "tsc:watch": "concurrently \" npx tsc -w \" \" npx ts-alias -w \"",
72
+ "login": "npm login --registry=https://registry.npmjs.org/",
65
73
  "publish:local": "pnpm version prerelease --preid dev --no-git-tag-version && pnpm publish --registry http://localhost:4873 --tag dev --access public --no-git-checks --json > ./publishLocal.json",
66
74
  "publish:prerelease": "pnpm publish --tag dev --access public --no-git-checks --registry=https://registry.npmjs.org/ --json > ./publish.json",
67
- "version:prerelease": "pnpm version prerelease --preid dev --no-git-tag-version"
75
+ "version:prerelease": "pnpm version prerelease --preid dev --no-git-tag-version",
76
+ "version": "pnpm version --no-git-tag-version"
68
77
  }
69
78
  }
package/src/browser.ts CHANGED
@@ -1,2 +1,4 @@
1
1
  export * from './lambda/browser.js';
2
- export * from './rehype/browser.js'
2
+ export * from './rehype/browser.js';
3
+
4
+ export * from './types/index.js';
@@ -0,0 +1,11 @@
1
+ import { CognitoIdentityProviderClient } from '@aws-sdk/client-cognito-identity-provider';
2
+
3
+ /**
4
+ * Convenience function if process.env.REGION is set
5
+ */
6
+ export function getCognitoClient() {
7
+ return new CognitoIdentityProviderClient({
8
+ region: process.env.REGION,
9
+ endpoint: `https://cognito-idp.${process.env.REGION}.amazonaws.com`
10
+ });
11
+ }
@@ -0,0 +1,175 @@
1
+ import {
2
+ error_lambda_badRequest,
3
+ error_lambda_conflict,
4
+ error_lambda_internal,
5
+ error_lambda_unauthorized,
6
+ error_lambda_forbidden,
7
+ error_lambda_notFound
8
+ } from '$lambda/errors.js';
9
+
10
+ export const error_cognito_forbidden = {
11
+ type: 'cognito_forbidden' as const
12
+ };
13
+ export const error_cognito_internal = {
14
+ type: 'cognito_internal' as const
15
+ };
16
+ export const error_cognito_role = {
17
+ type: 'cognito_role' as const
18
+ };
19
+ export const error_cognito_input = {
20
+ type: 'cognito_input' as const
21
+ };
22
+ export const error_cognito_auth = {
23
+ type: 'cognito_auth' as const
24
+ };
25
+ export const error_cognito_notFound = {
26
+ type: 'cognito_notFound' as const
27
+ };
28
+ export const error_cognito_userNotFound = {
29
+ type: 'cognito_userNotFound' as const
30
+ };
31
+ export const error_cognito_tooManyRequests = {
32
+ type: 'cognito_tooManyRequests' as const
33
+ };
34
+ export const error_cognito_passwordPolicy = {
35
+ type: 'cognito_passwordPolicy' as const
36
+ };
37
+ export const error_cognito_passwordHistory = {
38
+ type: 'cognito_passwordHistory' as const
39
+ };
40
+ export const error_cognito_passwordResetRequired = {
41
+ type: 'cognito_passwordResetRequired' as const
42
+ };
43
+
44
+ // Confirm forgot password
45
+ export const error_cognito_codeExpired = {
46
+ type: 'cognito_codeExpired' as const
47
+ };
48
+ export const error_cognito_codeMismatch = {
49
+ type: 'cognito_codeMismatch' as const
50
+ };
51
+
52
+ // Forgot password
53
+ export const error_cognito_delivery = {
54
+ type: 'cognito_delivery' as const
55
+ };
56
+ // Confirm signup
57
+ export const error_cognito_userExists = {
58
+ type: 'cognito_userExists' as const
59
+ };
60
+
61
+ export type type_error_cognito_forbidden = typeof error_cognito_forbidden;
62
+ export type type_error_cognito_internal = typeof error_cognito_internal;
63
+ export type type_error_cognito_role = typeof error_cognito_role;
64
+ export type type_error_cognito_input = typeof error_cognito_input;
65
+ export type type_error_cognito_auth = typeof error_cognito_auth;
66
+ export type type_error_cognito_notFound = typeof error_cognito_notFound;
67
+ export type type_error_cognito_userNotFound = typeof error_cognito_userNotFound;
68
+ export type type_error_cognito_tooManyRequests = typeof error_cognito_tooManyRequests;
69
+ export type type_error_cognito_passwordPolicy = typeof error_cognito_passwordPolicy;
70
+ export type type_error_cognito_passwordHistory = typeof error_cognito_passwordHistory;
71
+ export type type_error_cognito_passwordResetRequired = typeof error_cognito_passwordResetRequired;
72
+ export type type_error_cognito_codeExpired = typeof error_cognito_codeExpired;
73
+ export type type_error_cognito_codeMismatch = typeof error_cognito_codeMismatch;
74
+ export type type_error_cognito_delivery = typeof error_cognito_delivery;
75
+ export type type_error_cognito_userExists = typeof error_cognito_userExists;
76
+
77
+ export type type_error_cognito =
78
+ | type_error_cognito_forbidden
79
+ | type_error_cognito_internal
80
+ | type_error_cognito_role
81
+ | type_error_cognito_input
82
+ | type_error_cognito_auth
83
+ | type_error_cognito_notFound
84
+ | type_error_cognito_userNotFound
85
+ | type_error_cognito_tooManyRequests
86
+ | type_error_cognito_passwordPolicy
87
+ | type_error_cognito_passwordHistory
88
+ | type_error_cognito_passwordResetRequired
89
+ | type_error_cognito_codeExpired
90
+ | type_error_cognito_codeMismatch
91
+ | type_error_cognito_delivery
92
+ | type_error_cognito_userExists;
93
+
94
+ const awsToCognitoErrorMap = {
95
+ ForbiddenException: error_cognito_forbidden,
96
+ NotAuthorizedException: error_cognito_auth,
97
+ UserNotConfirmedException: error_cognito_auth,
98
+ UserNotFoundException: error_cognito_userNotFound,
99
+ ResourceNotFoundException: error_cognito_notFound,
100
+ InvalidParameterException: error_cognito_input,
101
+ InvalidPasswordException: error_cognito_passwordPolicy,
102
+ PasswordHistoryPolicyViolationException: error_cognito_passwordHistory,
103
+ PasswordResetRequiredException: error_cognito_passwordResetRequired,
104
+ LimitExceededException: error_cognito_tooManyRequests,
105
+ TooManyRequestsException: error_cognito_tooManyRequests,
106
+ InternalErrorException: error_cognito_internal,
107
+ // Confirm forgot password
108
+ CodeMismatchException: error_cognito_codeMismatch,
109
+ ExpiredCodeException: error_cognito_codeExpired,
110
+ TooManyFailedAttemptsException: error_cognito_tooManyRequests,
111
+ UnexpectedLambdaException: error_cognito_internal,
112
+ InvalidLambdaResponseException: error_cognito_internal,
113
+ UserLambdaValidationException: error_cognito_internal,
114
+ // Forgot password
115
+ InvalidEmailRoleAccessPolicyException: error_cognito_role,
116
+ InvalidSmsRoleAccessPolicyException: error_cognito_role,
117
+ InvalidSmsRoleTrustRelationshipException: error_cognito_role,
118
+ CodeDelliveryFailureException: error_cognito_delivery,
119
+ // Confirm signup
120
+ AliasExistsException: error_cognito_userExists,
121
+ // Login
122
+ InvalidUserPoolConfigurationException: error_cognito_internal,
123
+ MFAMethodNotFoundException: error_cognito_notFound,
124
+ UnsupportedOperationException: error_cognito_internal,
125
+ // Reset password
126
+ SoftwareTokenMFANotFoundException: error_cognito_notFound,
127
+ // Sign up
128
+ UsernameExistsException: error_cognito_userExists
129
+ } as const;
130
+
131
+ /**
132
+ * Gets a generic error from the name of the aws error
133
+ */
134
+ export function error_cognito(error: Error): type_error_cognito {
135
+ const type = error.name as keyof typeof awsToCognitoErrorMap;
136
+ if (awsToCognitoErrorMap[type] === undefined) console.warn(`${type} is not present in the cognito error map`);
137
+
138
+ console.error(`Cognito error: ${type}`, error);
139
+
140
+ return awsToCognitoErrorMap[type] || error_cognito_internal;
141
+ }
142
+
143
+ /**
144
+ * Converts a cognito error to a lambda error.
145
+ * Basically just for narrowing it down a bit
146
+ */
147
+ export function error_lambda_fromCognito(e: type_error_cognito) {
148
+ switch (e.type) {
149
+ case 'cognito_auth':
150
+ return error_lambda_unauthorized('Not authorized');
151
+ case 'cognito_forbidden':
152
+ return error_lambda_forbidden('Forbidden');
153
+ case 'cognito_internal':
154
+ case 'cognito_role':
155
+ return error_lambda_internal('Internal server error');
156
+ case 'cognito_input':
157
+ return error_lambda_badRequest('There is an issue with your request');
158
+ case 'cognito_notFound':
159
+ return error_lambda_notFound('Resource not found');
160
+ case 'cognito_userNotFound':
161
+ return error_lambda_notFound('User not found');
162
+ case 'cognito_tooManyRequests':
163
+ return error_lambda_badRequest('Too many requests');
164
+ case 'cognito_passwordPolicy':
165
+ return error_lambda_badRequest('Password does not meet policy requirements');
166
+ case 'cognito_passwordHistory':
167
+ return error_lambda_conflict('Password was used recently');
168
+ case 'cognito_passwordResetRequired':
169
+ return error_lambda_badRequest('Password reset required');
170
+ case 'cognito_delivery':
171
+ return error_lambda_internal('Delivery failed for the provided email or phone number');
172
+ default:
173
+ return error_lambda_internal('Unknown error');
174
+ }
175
+ }
@@ -0,0 +1,5 @@
1
+ export * from './client.js';
2
+ export * from './errors.js';
3
+
4
+ export * from './user.js';
5
+ export * from './password.js';
@@ -0,0 +1,233 @@
1
+ import {
2
+ AdminInitiateAuthCommand,
3
+ ChangePasswordCommand,
4
+ ConfirmForgotPasswordCommand,
5
+ ConfirmSignUpCommand,
6
+ ForgotPasswordCommand,
7
+ GlobalSignOutCommand,
8
+ RespondToAuthChallengeCommand,
9
+ SignUpCommand
10
+ } from '@aws-sdk/client-cognito-identity-provider';
11
+ import type { type_error_cognito } from './errors.js';
12
+ import { error_cognito } from './errors.js';
13
+ import { getCognitoClient } from './client.js';
14
+ import { ResultAsync } from 'neverthrow';
15
+ import { createHmac } from 'crypto';
16
+
17
+ const clientId = process.env.COGNITO_CLIENT_ID!;
18
+ const clientSecret = process.env.COGNITO_CLIENT_SECRET!;
19
+ const userPoolId = process.env.COGNITO_USER_POOL_ID!;
20
+
21
+ export function computeSecretHash(username: string, clientId: string, clientSecret: string): string {
22
+ return createHmac('SHA256', clientSecret)
23
+ .update(username + clientId)
24
+ .digest('base64');
25
+ }
26
+
27
+ // ---- Change password ---- //
28
+
29
+ /**
30
+ * Changes a users password
31
+ * Wraps the cognito sdk to use neverthrow
32
+ */
33
+ export const changePassword = ResultAsync.fromThrowable(
34
+ async (accessToken: string, oldPassword: string, newPassword: string) => {
35
+ const cognitoClient = getCognitoClient();
36
+ return cognitoClient.send(
37
+ new ChangePasswordCommand({
38
+ AccessToken: accessToken,
39
+ PreviousPassword: oldPassword,
40
+ ProposedPassword: newPassword
41
+ })
42
+ );
43
+ },
44
+ (e) => {
45
+ console.error('ChangePasswordCommand error', e);
46
+ return error_cognito(e as Error) as type_error_cognito;
47
+ }
48
+ );
49
+
50
+ // ---- Confirm Forgot password ---- //
51
+
52
+ /**
53
+ * Changes the password with the confirmation code sent to the email.
54
+ * Assumes the existence of process.env.COGNITO_CLIENT_ID and COGNITO_CLIENT_SECRET
55
+ * @param username - username or any of their alias attributes
56
+ * @param confirmationCode
57
+ * @param newPassword
58
+ */
59
+ export const confirmForgotPassword = ResultAsync.fromThrowable(
60
+ (data: { username: string; confirmationCode: string; newPassword: string }) => {
61
+ const cognitoClient = getCognitoClient();
62
+ return cognitoClient.send(
63
+ new ConfirmForgotPasswordCommand({
64
+ ClientId: clientId,
65
+ Username: data.username,
66
+ ConfirmationCode: data.confirmationCode,
67
+ Password: data.newPassword,
68
+ SecretHash: computeSecretHash(data.username, clientId!, clientSecret!)
69
+ })
70
+ );
71
+ },
72
+ (e) => {
73
+ console.error('ConfirmForgotPasswordCommand error', e);
74
+ return error_cognito(e as Error) as type_error_cognito;
75
+ }
76
+ );
77
+
78
+ // ---- Confirm Signup ---- //
79
+
80
+ /**
81
+ * Confirms signup
82
+ * @param username - username or any alias attribute
83
+ */
84
+ export const confirmSignup = ResultAsync.fromThrowable(
85
+ (data: { username: string; confirmationCode: string }) => {
86
+ const cognitoClient = getCognitoClient();
87
+ return cognitoClient.send(
88
+ new ConfirmSignUpCommand({
89
+ ClientId: clientId,
90
+ Username: data.username,
91
+ ConfirmationCode: data.confirmationCode,
92
+ SecretHash: computeSecretHash(data.username, clientId, clientSecret)
93
+ })
94
+ );
95
+ },
96
+ (e) => {
97
+ console.error('ConfirmSignUpCommand error', e);
98
+ return error_cognito(e as Error) as type_error_cognito;
99
+ }
100
+ );
101
+
102
+ // ---- Forgot password ---- //
103
+
104
+ /**
105
+ * Sends an email for you to reset your password
106
+ */
107
+ export const forgotPassword = ResultAsync.fromThrowable(
108
+ (data: { username: string }) => {
109
+ const cognitoClient = getCognitoClient();
110
+ return cognitoClient.send(
111
+ new ForgotPasswordCommand({
112
+ ClientId: clientId,
113
+ Username: data.username,
114
+ SecretHash: computeSecretHash(data.username, clientId, clientSecret)
115
+ })
116
+ );
117
+ },
118
+ (e) => {
119
+ console.error('ForgotPasswordCommand error', e);
120
+ return error_cognito(e as Error) as type_error_cognito;
121
+ }
122
+ );
123
+
124
+ // ---- Login ---- //
125
+
126
+ export const login = ResultAsync.fromThrowable(
127
+ (data: { username: string; password: string }) => {
128
+ const cognitoClient = getCognitoClient();
129
+ return cognitoClient.send(
130
+ new AdminInitiateAuthCommand({
131
+ AuthFlow: 'ADMIN_USER_PASSWORD_AUTH',
132
+ ClientId: clientId,
133
+ UserPoolId: userPoolId,
134
+ AuthParameters: {
135
+ USERNAME: data.username,
136
+ PASSWORD: data.password,
137
+ SECRET_HASH: computeSecretHash(data.username, clientId, clientSecret)
138
+ }
139
+ })
140
+ );
141
+ },
142
+ (e) => {
143
+ console.error('AdminInitiateAuthCommand error', e);
144
+ return error_cognito(e as Error) as type_error_cognito;
145
+ }
146
+ );
147
+
148
+ // ---- Refresh token ---- //
149
+
150
+ export const refreshTokens = ResultAsync.fromThrowable(
151
+ (data: { username: string; refreshToken: string }) => {
152
+ const cognitoClient = getCognitoClient();
153
+ return cognitoClient.send(
154
+ new AdminInitiateAuthCommand({
155
+ AuthFlow: 'REFRESH_TOKEN_AUTH',
156
+ ClientId: clientId,
157
+ UserPoolId: userPoolId,
158
+ AuthParameters: {
159
+ REFRESH_TOKEN: data.refreshToken,
160
+ SECRET_HASH: computeSecretHash(data.username, clientId, clientSecret)
161
+ }
162
+ })
163
+ );
164
+ },
165
+ (e) => {
166
+ console.error('AdminInitiateAuthCommand error', e);
167
+ return error_cognito(e as Error) as type_error_cognito;
168
+ }
169
+ );
170
+
171
+ // ---- Logout ---- //
172
+ export const logout = ResultAsync.fromThrowable(
173
+ (accessToken: string) => {
174
+ const cognitoClient = getCognitoClient();
175
+ // GlobalSignOut invalidates all refresh tokens associated with user
176
+ return cognitoClient.send(new GlobalSignOutCommand({ AccessToken: accessToken }));
177
+ },
178
+ (e) => {
179
+ console.error('GlobalSignOutCommand error', e);
180
+ return error_cognito(e as Error);
181
+ }
182
+ );
183
+
184
+ // ---- Reset password ---- //
185
+
186
+ export const resetPassword = ResultAsync.fromThrowable(
187
+ (data: { session: string; newPassword: string; username: string }) => {
188
+ const cognitoClient = getCognitoClient();
189
+ return cognitoClient.send(
190
+ new RespondToAuthChallengeCommand({
191
+ ChallengeName: 'NEW_PASSWORD_REQUIRED',
192
+ ClientId: clientId,
193
+ Session: data.session,
194
+ ChallengeResponses: {
195
+ SECRET_HASH: computeSecretHash(data.username, clientId, clientSecret),
196
+ NEW_PASSWORD: data.newPassword,
197
+ USERNAME: data.username
198
+ }
199
+ })
200
+ );
201
+ },
202
+ (e) => {
203
+ console.error('RespondToAuthChallengeCommand error', e);
204
+ return error_cognito(e as Error) as type_error_cognito;
205
+ }
206
+ );
207
+
208
+ // ---- Sign up ---- //
209
+ export const signUp = ResultAsync.fromThrowable(
210
+ (data: { username: string; password: string } & Record<string, unknown>) => {
211
+ const cognitoClient = getCognitoClient();
212
+ const secretHash = computeSecretHash(data.username, clientId, clientSecret);
213
+
214
+ return cognitoClient.send(
215
+ new SignUpCommand({
216
+ ClientId: clientId,
217
+ Username: data.username,
218
+ Password: data.password,
219
+ SecretHash: secretHash,
220
+ UserAttributes: Object.entries(data)
221
+ .filter(([key]) => key !== 'username' && key !== 'password')
222
+ .map(([key, value]) => ({
223
+ Name: key,
224
+ Value: value as string
225
+ }))
226
+ })
227
+ );
228
+ },
229
+ (e) => {
230
+ console.error('SignUpCommand error', e);
231
+ return error_cognito(e as Error) as type_error_cognito;
232
+ }
233
+ );
@@ -0,0 +1,46 @@
1
+ import type {
2
+ AdminGetUserCommandOutput,
3
+ AttributeType,
4
+ CognitoIdentityProviderServiceException
5
+ } from '@aws-sdk/client-cognito-identity-provider';
6
+ import { AdminGetUserCommand } from '@aws-sdk/client-cognito-identity-provider';
7
+ import { getCognitoClient } from './client.js';
8
+ import { ResultAsync } from 'neverthrow';
9
+ import { error_cognito } from './errors.js';
10
+
11
+ export type UserRes = Omit<AdminGetUserCommandOutput, 'UserAttributes'> & { UserAttributes: Record<string, string> };
12
+
13
+ /**
14
+ * Performs an AdminGetUserCommand and extracts the user attributes into an object
15
+ */
16
+ export const getUserDetails = ResultAsync.fromThrowable(
17
+ async (username: string) => {
18
+ console.log('getUserDetails: Getting details for user: ', username);
19
+ const UserPoolId = process.env.COGNITO_USER_POOL_ID;
20
+ const cognitoClient = getCognitoClient();
21
+ const res = await cognitoClient.send(new AdminGetUserCommand({ UserPoolId, Username: username }));
22
+ return {
23
+ ...res,
24
+ UserAttributes: extractAttributes(res.UserAttributes)
25
+ } as UserRes;
26
+ },
27
+ (e) => {
28
+ console.error('getUserDetails:error:', e);
29
+ return error_cognito(e as CognitoIdentityProviderServiceException);
30
+ }
31
+ );
32
+
33
+ /**
34
+ * @returns An object of attributes with their names as keys and values as values.
35
+ */
36
+ export function extractAttributes(attrs: AttributeType[] | undefined) {
37
+ const attributes: Record<string, string> = {};
38
+ if (attrs) {
39
+ for (const attr of attrs) {
40
+ if (attr.Name && attr.Value) {
41
+ attributes[attr.Name] = attr.Value;
42
+ }
43
+ }
44
+ }
45
+ return attributes;
46
+ }
@@ -0,0 +1,11 @@
1
+ import { error_lambda_internal } from '$lambda/errors.js';
2
+
3
+ export const error_dynamo = {
4
+ type: 'dynamo' as const
5
+ };
6
+
7
+ export type type_error_dynamo = typeof error_dynamo;
8
+
9
+ export function error_lambda_fromDynamo(e: type_error_dynamo) {
10
+ return error_lambda_internal('Internal server error');
11
+ }
@@ -0,0 +1 @@
1
+ export * from './errors.js';
package/src/index.ts CHANGED
@@ -1,3 +1,11 @@
1
+ // AWS
1
2
  export * from './lambda/index.js';
3
+ export * from './cognito/index.js';
4
+ export * from './s3/index.js';
5
+ export * from './dynamo/index.js';
6
+ export * from './ses/index.js';
7
+
2
8
  export * from './rehype/index.js';
3
9
  export * from './utils/index.js';
10
+
11
+ export * from './types/index.js';
@@ -1,3 +1,5 @@
1
1
  export * from './client-types.js';
2
2
  export * from './client.js';
3
3
  export * from './handlerUtils.js';
4
+ export * from './serializer.js';
5
+ export * from './deserializer.js';