providing password reset services for a long while: circa 2025
1import { slackApp } from "../index";
2
3const signup = async () => {
4 slackApp.action("create-account", async ({ context }) => {
5 if (context?.respond)
6 await context.respond({
7 response_type: "ephemeral",
8 text: "sweet! i'll need a password from you then!",
9 blocks: [
10 {
11 type: "section",
12 text: {
13 type: "mrkdwn",
14 text: "sweet! i'll need a password from you then!",
15 },
16 },
17 {
18 type: "input",
19 dispatch_action: true,
20 block_id: "password",
21 element: {
22 type: "plain_text_input",
23 action_id: "set_password",
24 focus_on_load: true,
25 min_length: 6,
26 placeholder: {
27 type: "plain_text",
28 text: "hackatime4ever!",
29 },
30 },
31 label: {
32 type: "plain_text",
33 text: "Password:",
34 },
35 },
36 {
37 type: "context",
38 elements: [
39 {
40 type: "mrkdwn",
41 text: "`Password must be at least 6 characters long.`",
42 },
43 ],
44 },
45 {
46 type: "actions",
47 elements: [
48 {
49 type: "button",
50 text: {
51 type: "plain_text",
52 text: "perfect, next!",
53 },
54 value: "next",
55 style: "primary",
56 action_id: "set_password",
57 },
58 {
59 type: "button",
60 text: {
61 type: "plain_text",
62 text: "i changed my mind",
63 },
64 value: "no",
65 action_id: "no-thanks",
66 },
67 ],
68 },
69 ],
70 });
71 });
72
73 slackApp.action("set_password", async ({ context, payload }) => {
74 if (!context?.respond) return;
75
76 // @ts-expect-error
77 const password: null | string =
78 payload?.state.values.password.set_password.value;
79 const user = (
80 await context.client.users.info({ user: context.userId as string })
81 ).user?.profile || { email: "unknown" };
82
83 if (
84 payload?.type !== "block_actions" ||
85 (payload?.actions[0].block_id === "password" && !password)
86 ) {
87 await context.respond({
88 response_type: "ephemeral",
89 text: "boooooo. `null` passwords are not allowed :(\n\nmake it at least 6 characters and try again!",
90 });
91 return;
92 }
93
94 await context.respond({
95 response_type: "ephemeral",
96 text: "does this look good to you? :eyes:",
97 blocks: [
98 {
99 type: "section",
100 text: {
101 type: "mrkdwn",
102 text: "does this look good to you? :eyes:",
103 },
104 },
105 { type: "divider" },
106 {
107 type: "section",
108 text: {
109 type: "mrkdwn",
110 text: `*hackatime profile*\n\norpheus mail: \`${user.email}\`\npassphrase: \`${password}\`\nusername: \`${context.userId}\``,
111 },
112 },
113 {
114 type: "actions",
115 elements: [
116 {
117 type: "button",
118 text: {
119 type: "plain_text",
120 text: "yes, looks good!",
121 },
122 value: password as string,
123 style: "primary",
124 action_id: "make-account",
125 },
126 {
127 type: "button",
128 text: {
129 type: "plain_text",
130 text: "no, let me change it",
131 },
132 value: "no",
133 action_id: "bad-info",
134 },
135 ],
136 },
137 ],
138 });
139 });
140
141 slackApp.action("make-account", async ({ context, payload }) => {
142 if (!context?.respond) return;
143 if (!context.client.users) return;
144
145 const user = (
146 await context.client.users.info({ user: context.userId as string })
147 ).user;
148
149 if (!user) return;
150
151 const name =
152 user.real_name || user.profile?.display_name || "Anonymous Hacker";
153
154 // @ts-expect-error
155 const password = payload?.actions[0].value;
156
157 const signup: { created: boolean; api_key: string } = await fetch(
158 "https://waka.hackclub.com/signup",
159 {
160 method: "POST",
161 headers: {
162 "Content-Type": "application/x-www-form-urlencoded",
163 Authorization: `Bearer ${process.env.HACKATIME_API_KEY}`,
164 },
165 body: new URLSearchParams({
166 location: user.tz as string,
167 username: context.userId as string,
168 name,
169 email: user.profile?.email || "",
170 password: password || "",
171 password_repeat: password || "",
172 }).toString(),
173 },
174 ).then((res) => res.json());
175
176 await context.respond({
177 response_type: "ephemeral",
178 text: "great! your account has been created :yay:",
179 blocks: [
180 {
181 type: "section",
182 text: {
183 type: "mrkdwn",
184 text: "great! your account has been created :yay:",
185 },
186 },
187 { type: "divider" },
188 {
189 type: "section",
190 text: {
191 type: "mrkdwn",
192 text: `you can now log in to the <https://waka.hackclub.com/login|Hackatime dashboard> with your username \`${context.userId}\` and password \`${password}\` :3c:`,
193 },
194 },
195 {
196 type: "context",
197 elements: [
198 {
199 type: "mrkdwn",
200 text: `your api key for the Hackatime API is \`${signup.api_key}\``,
201 },
202 ],
203 },
204 ],
205 });
206 });
207
208 slackApp.action("bad-info", async ({ context }) => {
209 if (context?.respond)
210 await context.respond({
211 response_type: "ephemeral",
212 text: "no worries! we can't really change the `username` or `email` but you can change your `password` if you'd like! just re-run this command :3c:",
213 });
214 });
215};
216
217export default signup;