chore: migrate untranslated files (#44462)
This commit is contained in:
committed by
GitHub
parent
f8eec5d3fb
commit
010e09ffb7
@@ -0,0 +1,172 @@
|
||||
---
|
||||
id: 587d824a367417b2b2512c45
|
||||
title: Anonymous Message Board
|
||||
challengeType: 4
|
||||
forumTopicId: 301568
|
||||
dashedName: anonymous-message-board
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Build a full stack JavaScript app that is functionally similar to this: <https://anonymous-message-board.freecodecamp.rocks/>.
|
||||
|
||||
Working on this project will involve you writing your code using one of the following methods:
|
||||
|
||||
- Clone [this GitHub repo](https://github.com/freeCodeCamp/boilerplate-project-messageboard/) and complete your project locally.
|
||||
- Use [our Replit starter project](https://replit.com/github/freeCodeCamp/boilerplate-project-messageboard) to complete your project.
|
||||
- Use a site builder of your choice to complete the project. Be sure to incorporate all the files from our GitHub repo.
|
||||
|
||||
When you are done, make sure a working demo of your project is hosted somewhere public. Then submit the URL to it in the `Solution Link` field. Optionally, also submit a link to your project's source code in the `GitHub Link` field.
|
||||
|
||||
# --instructions--
|
||||
|
||||
1. Set `NODE_ENV` to test without quotes when ready to write tests and DB to your databases connection string (in `.env`)
|
||||
2. Recommended to create controllers/handlers and handle routing in `routes/api.js`
|
||||
3. You will add any security features to `server.js`
|
||||
|
||||
Write the following tests in `tests/2_functional-tests.js`:
|
||||
|
||||
- Creating a new thread: POST request to `/api/threads/{board}`
|
||||
- Viewing the 10 most recent threads with 3 replies each: GET request to `/api/threads/{board}`
|
||||
- Deleting a thread with the incorrect password: DELETE request to `/api/threads/{board}` with an invalid `delete_password`
|
||||
- Deleting a thread with the correct password: DELETE request to `/api/threads/{board}` with a valid `delete_password`
|
||||
- Reporting a thread: PUT request to `/api/threads/{board}`
|
||||
- Creating a new reply: POST request to `/api/replies/{board}`
|
||||
- Viewing a single thread with all replies: GET request to `/api/replies/{board}`
|
||||
- Deleting a reply with the incorrect password: DELETE request to `/api/replies/{board}` with an invalid `delete_password`
|
||||
- Deleting a reply with the correct password: DELETE request to `/api/replies/{board}` with a valid `delete_password`
|
||||
- Reporting a reply: PUT request to `/api/replies/{board}`
|
||||
|
||||
# --hints--
|
||||
|
||||
You can provide your own project, not the example URL.
|
||||
|
||||
```js
|
||||
(getUserInput) => {
|
||||
assert(
|
||||
!/.*\/anonymous-message-board\.freecodecamp\.rocks/.test(
|
||||
getUserInput('url')
|
||||
)
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
Only allow your site to be loaded in an iFrame on your own pages.
|
||||
|
||||
```js
|
||||
async (getUserInput) => {
|
||||
const data = await fetch(getUserInput('url') + '/_api/app-info');
|
||||
const parsed = await data.json();
|
||||
assert.isTrue(parsed.headers['x-frame-options']?.includes('SAMEORIGIN'));
|
||||
};
|
||||
```
|
||||
|
||||
Do not allow DNS prefetching.
|
||||
|
||||
```js
|
||||
async (getUserInput) => {
|
||||
const data = await fetch(getUserInput('url') + '/_api/app-info');
|
||||
const parsed = await data.json();
|
||||
assert.isTrue(parsed.headers['x-dns-prefetch-control']?.includes('off'));
|
||||
};
|
||||
```
|
||||
|
||||
Only allow your site to send the referrer for your own pages.
|
||||
|
||||
```js
|
||||
async (getUserInput) => {
|
||||
const data = await fetch(getUserInput('url') + '/_api/app-info');
|
||||
const parsed = await data.json();
|
||||
assert.isTrue(parsed.headers['referrer-policy']?.includes('same-origin'));
|
||||
};
|
||||
```
|
||||
|
||||
You can send a POST request to `/api/threads/{board}` with form data including `text` and `delete_password`. The saved database record will have at least the fields `_id`, `text`, `created_on`(date & time), `bumped_on`(date & time, starts same as `created_on`), `reported` (boolean), `delete_password`, & `replies` (array).
|
||||
|
||||
```js
|
||||
async (getUserInput) => {
|
||||
const date = new Date();
|
||||
const text = `fcc_test_${date}`;
|
||||
const deletePassword = 'delete_me';
|
||||
const data = { text, delete_password: deletePassword };
|
||||
const url = getUserInput('url');
|
||||
const res = await fetch(url + '/api/threads/fcc_test', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(data)
|
||||
});
|
||||
if (res.ok) {
|
||||
const checkData = await fetch(url + '/api/threads/fcc_test');
|
||||
const parsed = await checkData.json();
|
||||
try {
|
||||
assert.equal(parsed[0].text, text);
|
||||
assert.isNotNull(parsed[0]._id);
|
||||
assert.equal(new Date(parsed[0].created_on).toDateString(), date.toDateString());
|
||||
assert.equal(parsed[0].bumped_on, parsed[0].created_on);
|
||||
assert.isArray(parsed[0].replies);
|
||||
} catch (err) {
|
||||
throw new Error(err.responseText || err.message);
|
||||
}
|
||||
} else {
|
||||
throw new Error(`${res.status} ${res.statusText}`);
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
You can send a POST request to `/api/replies/{board}` with form data including `text`, `delete_password`, & `thread_id`. This will update the `bumped_on` date to the comment's date. In the thread's `replies` array, an object will be saved with at least the properties `_id`, `text`, `created_on`, `delete_password`, & `reported`.
|
||||
|
||||
```js
|
||||
|
||||
```
|
||||
|
||||
You can send a GET request to `/api/threads/{board}`. Returned will be an array of the most recent 10 bumped threads on the board with only the most recent 3 replies for each. The `reported` and `delete_password` fields will not be sent to the client.
|
||||
|
||||
```js
|
||||
|
||||
```
|
||||
|
||||
You can send a GET request to `/api/replies/{board}?thread_id={thread_id}`. Returned will be the entire thread with all its replies, also excluding the same fields from the client as the previous test.
|
||||
|
||||
```js
|
||||
|
||||
```
|
||||
|
||||
You can send a DELETE request to `/api/threads/{board}` and pass along the `thread_id` & `delete_password` to delete the thread. Returned will be the string `incorrect password` or `success`.
|
||||
|
||||
```js
|
||||
|
||||
```
|
||||
|
||||
You can send a DELETE request to `/api/replies/{board}` and pass along the `thread_id`, `reply_id`, & `delete_password`. Returned will be the string `incorrect password` or `success`. On success, the text of the `reply_id` will be changed to `[deleted]`.
|
||||
|
||||
```js
|
||||
|
||||
```
|
||||
|
||||
You can send a PUT request to `/api/threads/{board}` and pass along the `thread_id`. Returned will be the string `success`. The `reported` value of the `thread_id` will be changed to `true`.
|
||||
|
||||
```js
|
||||
|
||||
```
|
||||
|
||||
You can send a PUT request to `/api/replies/{board}` and pass along the `thread_id` & `reply_id`. Returned will be the string `success`. The `reported` value of the `reply_id` will be changed to `true`.
|
||||
|
||||
```js
|
||||
|
||||
```
|
||||
|
||||
All 10 functional tests are complete and passing.
|
||||
|
||||
```js
|
||||
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
/**
|
||||
Backend challenges don't need solutions,
|
||||
because they would need to be tested against a full working project.
|
||||
Please check our contributing guidelines to learn more.
|
||||
*/
|
||||
```
|
@@ -0,0 +1,95 @@
|
||||
---
|
||||
id: 5e46f979ac417301a38fb932
|
||||
title: Port Scanner
|
||||
challengeType: 10
|
||||
forumTopicId: 462372
|
||||
helpCategory: Python
|
||||
dashedName: port-scanner
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
You will be [working on this project with our Replit starter code](https://replit.com/github/freeCodeCamp/boilerplate-port-scanner).
|
||||
|
||||
We are still developing the interactive instructional part of the Python curriculum. For now, here are some videos on the freeCodeCamp.org YouTube channel that will teach you everything you need to know to complete this project:
|
||||
|
||||
- [Python for Everybody Video Course](https://www.freecodecamp.org/news/python-for-everybody/) (14 hours)
|
||||
|
||||
- [Learn Python Video Course](https://www.freecodecamp.org/news/learn-python-video-course/) (10 hours)
|
||||
|
||||
# --instructions--
|
||||
|
||||
Create a port scanner using Python.
|
||||
|
||||
In the `port_scanner.py` file, create a function called `get_open_ports` that takes a `target` argument and a `port_range` argument. `target` can be a URL or IP address. `port_range` is a list of two numbers indicating the first and last numbers of the range of ports to check.
|
||||
|
||||
Here are examples of how the function may be called:
|
||||
|
||||
```py
|
||||
get_open_ports("209.216.230.240", [440, 445])
|
||||
get_open_ports("www.stackoverflow.com", [79, 82])
|
||||
```
|
||||
|
||||
The function should return a list of open ports in the given range.
|
||||
|
||||
The `get_open_ports` function should also take an optional third argument of `True` to indicate "Verbose" mode. If this is set to true, the function should return a descriptive string instead of a list of ports.
|
||||
|
||||
Here is the format of the string that should be returned in verbose mode (text inside `{}` indicates the information that should appear):
|
||||
|
||||
```bash
|
||||
Open ports for {URL} ({IP address})
|
||||
PORT SERVICE
|
||||
{port} {service name}
|
||||
{port} {service name}
|
||||
```
|
||||
|
||||
You can use the dictionary in `common_ports.py` to get the correct service name for each port.
|
||||
|
||||
For example, if the function is called like this:
|
||||
|
||||
```py
|
||||
port_scanner.get_open_ports("scanme.nmap.org", [20, 80], True)
|
||||
```
|
||||
|
||||
It should return the following:
|
||||
|
||||
```bash
|
||||
Open ports for scanme.nmap.org (45.33.32.156)
|
||||
PORT SERVICE
|
||||
22 ssh
|
||||
80 http
|
||||
```
|
||||
|
||||
Make sure to include proper spacing and new line characters.
|
||||
|
||||
If the URL passed into the `get_open_ports` function is invalid, the function should return the string: "Error: Invalid hostname".
|
||||
|
||||
If the IP address passed into the `get_open_ports` function is invalid, the function should return the string: "Error: Invalid IP address".
|
||||
|
||||
## Development
|
||||
|
||||
Write your code in `port_scanner.py`. For development, you can use `main.py` to test your code. Click the "run" button and `main.py` will run.
|
||||
|
||||
## Testing
|
||||
|
||||
The unit tests for this project are in `test_module.py`. We imported the tests from `test_module.py` to `main.py` for your convenience. The tests will run automatically whenever you hit the "run" button.
|
||||
|
||||
## Submitting
|
||||
|
||||
Copy your project's URL and submit it to freeCodeCamp.
|
||||
|
||||
# --hints--
|
||||
|
||||
It should pass all Python tests.
|
||||
|
||||
```js
|
||||
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```py
|
||||
# Python challenges don't need solutions,
|
||||
# because they would need to be tested against a full working project.
|
||||
# Please check our contributing guidelines to learn more.
|
||||
```
|
@@ -0,0 +1,72 @@
|
||||
---
|
||||
id: 5e46f983ac417301a38fb933
|
||||
title: SHA-1 Password Cracker
|
||||
challengeType: 10
|
||||
forumTopicId: 462374
|
||||
helpCategory: Python
|
||||
dashedName: sha-1-password-cracker
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
You will be [working on this project with our Replit starter code](https://replit.com/github/freeCodeCamp/boilerplate-SHA-1-password-cracker).
|
||||
|
||||
We are still developing the interactive instructional part of the Python curriculum. For now, here are some videos on the freeCodeCamp.org YouTube channel that will teach you everything you need to know to complete this project:
|
||||
|
||||
- [Python for Everybody Video Course](https://www.freecodecamp.org/news/python-for-everybody/) (14 hours)
|
||||
|
||||
- [Learn Python Video Course](https://www.freecodecamp.org/news/learn-python-video-course/) (10 hours)
|
||||
|
||||
# --instructions--
|
||||
|
||||
Passwords should never be stored in plain text. They should be stored as hashes, just in case the password list is discovered. However, not all hashes are created equal.
|
||||
|
||||
For this project you will learn about the importance of good security by creating a password cracker to figure out passwords that were hashed using SHA-1.
|
||||
|
||||
Create a function that takes in a SHA-1 hash of a password and returns the password if it is one of the top 10,000 passwords used. If the SHA-1 hash is NOT of a password in the database, return "PASSWORD NOT IN DATABASE".
|
||||
|
||||
The function should hash each password from `top-10000-passwords.txt` and compare it to the hash passed into the function.
|
||||
|
||||
The function should take an optional second argument named `use_salts`. If set to true, each salt string from the file `known-salts.txt` should be appended AND prepended to each password from `top-10000-passwords.txt` before hashing and before comparing it to the hash passed into the function.
|
||||
|
||||
Here are some hashed passwords to test the function with:
|
||||
|
||||
- `b305921a3723cd5d70a375cd21a61e60aabb84ec` should return "sammy123"
|
||||
- `c7ab388a5ebefbf4d550652f1eb4d833e5316e3e` should return "abacab"
|
||||
- `5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8` should return "password"
|
||||
|
||||
Here are some hashed passwords to test the function with when `use_salts` is set to `True`:
|
||||
|
||||
- `53d8b3dc9d39f0184144674e310185e41a87ffd5` should return "superman"
|
||||
- `da5a4e8cf89539e66097acd2f8af128acae2f8ae` should return "q1w2e3r4t5"
|
||||
- `ea3f62d498e3b98557f9f9cd0d905028b3b019e1` should return "bubbles1"
|
||||
|
||||
The `hashlib` library has been imported for you. You should condider using it in your code. [Learn more about "hashlib" here.](https://docs.python.org/3/library/hashlib.html)
|
||||
|
||||
## Development
|
||||
|
||||
Write your code in `password_cracker.py`. For development, you can use `main.py` to test your code. Click the "run" button and `main.py` will run.
|
||||
|
||||
## Testing
|
||||
|
||||
The unit tests for this project are in `test_module.py`. We imported the tests from `test_module.py` to `main.py` for your convenience. The tests will run automatically whenever you hit the "run" button.
|
||||
|
||||
## Submitting
|
||||
|
||||
Copy your project's URL and submit it to freeCodeCamp.
|
||||
|
||||
# --hints--
|
||||
|
||||
It should pass all Python tests.
|
||||
|
||||
```js
|
||||
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```py
|
||||
# Python challenges don't need solutions,
|
||||
# because they would need to be tested against a full working project.
|
||||
# Please check our contributing guidelines to learn more.
|
||||
```
|
@@ -0,0 +1,136 @@
|
||||
---
|
||||
id: 587d824a367417b2b2512c44
|
||||
title: Stock Price Checker
|
||||
challengeType: 4
|
||||
forumTopicId: 301572
|
||||
dashedName: stock-price-checker
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Build a full stack JavaScript app that is functionally similar to this: <https://stock-price-checker.freecodecamp.rocks/>.
|
||||
|
||||
Since all reliable stock price APIs require an API key, we've built a workaround. Use <https://stock-price-checker-proxy.freecodecamp.rocks/> to get up-to-date stock price information without needing to sign up for your own key.
|
||||
|
||||
Working on this project will involve you writing your code using one of the following methods:
|
||||
|
||||
- Clone [this GitHub repo](https://github.com/freeCodeCamp/boilerplate-project-stockchecker/) and complete your project locally.
|
||||
- Use [our Replit starter project](https://replit.com/github/freeCodeCamp/boilerplate-project-stockchecker) to complete your project.
|
||||
- Use a site builder of your choice to complete the project. Be sure to incorporate all the files from our GitHub repo.
|
||||
|
||||
When you are done, make sure a working demo of your project is hosted somewhere public. Then submit the URL to it in the `Solution Link` field. Optionally, also submit a link to your project's source code in the `GitHub Link` field.
|
||||
|
||||
# --instructions--
|
||||
|
||||
1. SET `NODE_ENV` to `test` without quotes and set `DB` to your MongoDB connection string
|
||||
2. Complete the project in `routes/api.js` or by creating a handler/controller
|
||||
3. You will add any security features to `server.js`
|
||||
4. You will create all of the functional tests in `tests/2_functional-tests.js`
|
||||
|
||||
**Note** Privacy Considerations: Due to the requirement that only 1 like per IP should be accepted, you will have to save IP addresses. It is important to remain compliant with data privacy laws such as the General Data Protection Regulation. One option is to get permission to save the user's data, but it is much simpler to anonymize it. For this challenge, remember to anonymize IP addresses before saving them to the database. If you need ideas on how to do this, you may choose to hash the data, truncate it, or set part of the IP address to 0.
|
||||
|
||||
Write the following tests in `tests/2_functional-tests.js`:
|
||||
|
||||
- Viewing one stock: GET request to `/api/stock-prices/`
|
||||
- Viewing one stock and liking it: GET request to `/api/stock-prices/`
|
||||
- Viewing the same stock and liking it again: GET request to `/api/stock-prices/`
|
||||
- Viewing two stocks: GET request to `/api/stock-prices/`
|
||||
- Viewing two stocks and liking them: GET request to `/api/stock-prices/`
|
||||
|
||||
# --hints--
|
||||
|
||||
You can provide your own project, not the example URL.
|
||||
|
||||
```js
|
||||
(getUserInput) => {
|
||||
assert(
|
||||
!/.*\/stock-price-checker\.freecodecamp\.rocks/.test(getUserInput('url'))
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
You should set the content security policies to only allow loading of scripts and CSS from your server.
|
||||
|
||||
```js
|
||||
async (getUserInput) => {
|
||||
const data = await fetch(getUserInput('url') + '/_api/app-info');
|
||||
const parsed = await data.json();
|
||||
assert.isTrue(
|
||||
parsed.headers['content-security-policy'].includes("script-src 'self'")
|
||||
);
|
||||
assert.isTrue(
|
||||
parsed.headers['content-security-policy'].includes("style-src 'self'")
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
You can send a `GET` request to `/api/stock-prices`, passing a NASDAQ stock symbol to a `stock` query parameter. The returned object will contain a property named `stockData`.
|
||||
|
||||
```js
|
||||
async (getUserInput) => {
|
||||
const data = await fetch(
|
||||
getUserInput('url') + '/api/stock-prices?stock=GOOG'
|
||||
);
|
||||
const parsed = await data.json();
|
||||
assert.property(parsed, 'stockData');
|
||||
};
|
||||
```
|
||||
|
||||
The `stockData` property includes the `stock` symbol as a string, the `price` as a number, and `likes` as a number.
|
||||
|
||||
```js
|
||||
async (getUserInput) => {
|
||||
const data = await fetch(
|
||||
getUserInput('url') + '/api/stock-prices?stock=GOOG'
|
||||
);
|
||||
const parsed = await data.json();
|
||||
const ticker = parsed.stockData;
|
||||
assert.typeOf(ticker.price, 'number');
|
||||
assert.typeOf(ticker.likes, 'number');
|
||||
assert.typeOf(ticker.stock, 'string');
|
||||
};
|
||||
```
|
||||
|
||||
You can also pass along a `like` field as `true` (boolean) to have your like added to the stock(s). Only 1 like per IP should be accepted.
|
||||
|
||||
```js
|
||||
|
||||
```
|
||||
|
||||
If you pass along 2 stocks, the returned value will be an array with information about both stocks. Instead of `likes`, it will display `rel_likes` (the difference between the likes on both stocks) for both `stockData` objects.
|
||||
|
||||
```js
|
||||
async (getUserInput) => {
|
||||
const data = await fetch(
|
||||
getUserInput('url') + '/api/stock-prices?stock=GOOG&stock=MSFT'
|
||||
);
|
||||
const parsed = await data.json();
|
||||
const ticker = parsed.stockData;
|
||||
assert.typeOf(ticker, 'array');
|
||||
assert.property(ticker[0], 'rel_likes');
|
||||
assert.property(ticker[1], 'rel_likes');
|
||||
};
|
||||
```
|
||||
|
||||
All 5 functional tests are complete and passing.
|
||||
|
||||
```js
|
||||
async (getUserInput) => {
|
||||
const tests = await fetch(getUserInput('url') + '/_api/get-tests');
|
||||
const parsed = await tests.json();
|
||||
assert.isTrue(parsed.length >= 5);
|
||||
parsed.forEach((test) => {
|
||||
assert.equal(test.state, 'passed');
|
||||
});
|
||||
};
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
/**
|
||||
Backend challenges don't need solutions,
|
||||
because they would need to be tested against a full working project.
|
||||
Please check our contributing guidelines to learn more.
|
||||
*/
|
||||
```
|
Reference in New Issue
Block a user