Skip to content

Commit 2f9e8ea

Browse files
committed
chore(a2): add skeleton code
1 parent c182fdb commit 2f9e8ea

File tree

12 files changed

+1489
-0
lines changed

12 files changed

+1489
-0
lines changed

a2/actions.js

Lines changed: 247 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,247 @@
1+
"use strict";
2+
3+
/*****************************************************************************
4+
* This is the JavaScript file that students need to modify to implement the
5+
* password safe application. The other file, client.js, should be fine
6+
* without modification. That file handles page navigation, event handler
7+
* binding, token setting/retrieving, preflighting, and provides some
8+
* utility functions that this file should use for encoding/decoding strings
9+
* and making server requests.
10+
*
11+
* Please do not use any method other than serverRequest to make requests to
12+
* the server! It handles a few things including tokens that you should not
13+
* reimplement.
14+
*
15+
* Most of the functions in this file handle a form submission. These
16+
* are passed as arguments the input/output DOM elements of the form that was
17+
* submitted. The "this" keyword for these functions is the form element
18+
* itself. The functions that handle form submissions are:
19+
* - login
20+
* - signup
21+
* - save
22+
* - load
23+
*
24+
* The other functions are each called for different reasons with different
25+
* parameters:
26+
* - loadSite -- This function is called to populate the input or output
27+
* elements of the add or load password form. The function
28+
* takes the site to load (a string) and the form elements
29+
* as parameters.
30+
* - logout -- This function is called when the logout link is clicked.
31+
* It should clean up any data and inform the server to log
32+
* out the user.
33+
* - credentials -- This is a utility function meant to be used by the
34+
* login function. It is not called from other client
35+
* code (in client.js)! The purpose of providing the
36+
* outline of this function is to help guide students
37+
* towards an implementation that is not too complicated
38+
* and to give ideas about how some steps can be
39+
* accomplished.
40+
*
41+
* The utility functions in client.js are:
42+
* - serverRequest -- Takes the server resource and parameters as arguments
43+
* and returns a promise with two properties:
44+
* * response (a JavaScript response object)
45+
* * json (the decoded data from the server)
46+
* - showContent -- Shows the specified page of the application. This is
47+
* how student code should redirect the site to other
48+
* pages after a user action.
49+
* - status -- displays a status message at the top of the page.
50+
* - serverStatus -- Takes the result of the serverRequest promise and
51+
* displays any status messages from it. This just
52+
* avoids some code duplication.
53+
* - bufferToHexString
54+
* - hexStringToUint8Array
55+
* - bufferToUtf8
56+
* - utf8ToUint8Array
57+
*
58+
* A few things you will need to know to succeed:
59+
* ---------------------------------------------------
60+
* Look at the MDN documentation for subtle crypto!
61+
* https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto
62+
* Also, you may want to use:
63+
* https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues
64+
*
65+
* The subtle crypto error messages are useless. Typical errors are due to
66+
* passing unexpected parameters to the functions. Take a look at the files
67+
* from Tutorial 4 for examples of using
68+
* crypto.subtle.importKey
69+
* crypto.subtle.sign
70+
* crypto.subtle.decrypt
71+
* You may also be interested in using
72+
* crypto.subtle.encrypt
73+
* crypto.subtle.digest
74+
*
75+
* The most common error is to pass a key or iv buffer that is the wrong size.
76+
* For AES-CBC, for example, the key must be length 16 or 32 bytes, and the
77+
* IV must be 16 bytes.
78+
*
79+
* To concatenate two typed Uint8Arrays (a1, a2), you can do the following:
80+
* let a3 = new Uint8Array(a1.length + a2.length);
81+
* a3.set(a1);
82+
* a3.set(a2, a1.length);
83+
*
84+
*****************************************************************************/
85+
86+
87+
/**
88+
* This is an async function that should return the username and password to send
89+
* to the server for login credentials.
90+
*/
91+
async function credentials(username, password) {
92+
var idResult;
93+
94+
// get any information needed to log in
95+
idResult = await serverRequest("identify", {
96+
"username": username
97+
});
98+
// bail if something went wrong
99+
if (!idResult.response.ok) {
100+
serverStatus(idResult);
101+
return 0;
102+
}
103+
104+
return idResult.json;
105+
}
106+
107+
/**
108+
* Called when the user submits the log-in form.
109+
*/
110+
function login(userInput, passInput) {
111+
// get the form fields
112+
var username = userInput.value,
113+
password = passInput.value;
114+
115+
credentials(username, password).then(function (idJson) {
116+
// do any needed work with the credentials
117+
118+
// Send a login request to the server.
119+
serverRequest("login", // resource to call
120+
{
121+
"username": username,
122+
"password": password
123+
} // this should be populated with needed parameters
124+
).then(function (result) {
125+
// If the login was successful, show the dashboard.
126+
if (result.response.ok) {
127+
// do any other work needed after successful login here
128+
129+
showContent("dashboard");
130+
131+
} else {
132+
// If the login failed, show the login page with an error message.
133+
serverStatus(result);
134+
}
135+
});
136+
137+
});
138+
}
139+
140+
/**
141+
* Called when the user submits the signup form.
142+
*/
143+
function signup(userInput, passInput, passInput2, emailInput) {
144+
// get the form fields
145+
var username = userInput.value,
146+
password = passInput.value,
147+
password2 = passInput2.value,
148+
email = emailInput.value;
149+
150+
// do any preprocessing on the user input here before sending to the server
151+
152+
// send the signup form to the server
153+
serverRequest("signup", // resource to call
154+
{
155+
"username": username,
156+
"password": password,
157+
"email": email
158+
} // this should be populated with needed parameters
159+
).then(function (result) {
160+
// if everything was good
161+
if (result.response.ok) {
162+
// do any work needed if the signup request succeeded
163+
164+
// go to the login page
165+
showContent("login");
166+
}
167+
// show the status message from the server
168+
serverStatus(result);
169+
});
170+
}
171+
172+
173+
/**
174+
* Called when the add password form is submitted.
175+
*/
176+
function save(siteInput, userInput, passInput) {
177+
var site = siteInput.value,
178+
siteuser = userInput.value,
179+
sitepasswd = passInput.value,
180+
encrypted; // this will need to be populated
181+
182+
// send the data, along with the encrypted password, to the server
183+
serverRequest("save", // the resource to call
184+
{
185+
"site": site,
186+
"siteuser": siteuser,
187+
"sitepasswd": encrypted
188+
} // this should be populated with any parameters the server needs
189+
).then(function (result) {
190+
if (result.response.ok) {
191+
// any work after a successful save should be done here
192+
193+
// update the sites list
194+
sites("save");
195+
}
196+
// show any server status messages
197+
serverStatus(result);
198+
});
199+
}
200+
201+
/**
202+
* Called when a site dropdown is changed to select a site.
203+
* This can be called from either the save or load page.
204+
* Note that, unlike all the other parameters to functions in
205+
* this file, siteName is a string (the site to load) and not
206+
* a form element.
207+
*/
208+
function loadSite(siteName, siteElement, userElement, passElement) {
209+
// do any preprocessing here
210+
211+
serverRequest("load", // the resource to call
212+
{
213+
"site": siteName
214+
} // populate with any parameters the server needs
215+
).then(function (result) {
216+
if (result.response.ok) {
217+
// do any work that needs to be done on success
218+
219+
} else {
220+
// on failure, show the login page and display any server status
221+
showContent("login");
222+
serverStatus(result);
223+
}
224+
});
225+
}
226+
227+
/**
228+
* Called when the decrypt password button is pressed.
229+
*/
230+
function load(siteInput, userInput, passInput) {
231+
// you will need to entirely populate this function
232+
}
233+
234+
/**
235+
* Called when the logout link is clicked.
236+
*/
237+
function logout() {
238+
// do any preprocessing needed
239+
240+
// tell the server to log out
241+
serverRequest("logout", {}).then(function (result) {
242+
if (result.response.ok) {
243+
showContent("login");
244+
}
245+
serverStatus(result);
246+
});
247+
}

0 commit comments

Comments
 (0)