diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 04adc238390..5949807740e 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -15,16 +15,16 @@ #### Type of Change -- [ ] Bug fix (non-breaking change which fixes an issue) -- [ ] New feature (non-breaking change which adds functionality) -- [ ] Breaking change (fix or feature that would cause existing functionality to change) +- [ ] Small bug fix (non-breaking change which fixes an issue) +- [ ] New feature (non-breaking change which adds new functionality) +- [ ] Breaking change (fix or feature that would change existing functionality) - [ ] Add new translation (feature adding new translations) #### Checklist: - + - [ ] Tested changes locally. -- [ ] Closes currently open issue (`Closes #XXXX`): Closes +- [ ] Closes currently open issue (e.g. `Closes #XXXX`): Closes #### Description diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7b3ab1b8602..a0084772889 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -166,7 +166,7 @@ Read the [Wiki article](https://github.com/FreeCodeCamp/FreeCodeCamp/wiki/How-To - **Do not add the issue number in the PR title**. - Examples: `Add Test Cases to Bonfire Drop It` `Correct typo in Waypoint Size Your Images` 4. In the body of your PR include a more detailed summary of the changes you made and why. - - If the PR is meant to fix an existing bug/issue, then, at the end of your PR's commit message, append the keyword `closes` and #xxxx (where xxxx is the issue number). Example: `closes #1337`. + - If the PR is meant to fix an existing bug/issue, then, at the end of your PR's description, append the keyword `closes` and #xxxx (where xxxx is the issue number). Example: `closes #1337`. This tells GitHub to close the existing issue, if the PR is merged. 5. Indicate if you have tested on a local copy of the site or not. diff --git a/client/index.js b/client/index.js index e5e7028aed2..bb310868344 100644 --- a/client/index.js +++ b/client/index.js @@ -18,8 +18,10 @@ import render from '../common/app/utils/render'; const log = debug('fcc:client'); const DOMContainer = document.getElementById('fcc'); const initialState = window.__fcc__.data; +const csrfToken = window.__fcc__.csrf.token; +initialState.app.csrfToken = csrfToken; -const serviceOptions = { xhrPath: '/services' }; +const serviceOptions = { xhrPath: '/services', context: { _csrf: csrfToken } }; Rx.config.longStackSupport = !!debug.enabled; const history = createHistory(); diff --git a/client/less/map.less b/client/less/map.less index b96cc734444..49ca40f0b35 100644 --- a/client/less/map.less +++ b/client/less/map.less @@ -2,7 +2,7 @@ * based off of https://github.com/gitterHQ/sidecar * license: MIT */ - + .map-aside { width:500px; @@ -90,6 +90,7 @@ margin: 0 auto; z-index: 2; top: 160px; + left: 0px; width: 100%; } } @@ -132,7 +133,6 @@ } .mapWrapper { - position:absolute; display: block; height: 100%; width: 100%; diff --git a/common/app/redux/reducer.js b/common/app/redux/reducer.js index 34520a75142..ef189c9390f 100644 --- a/common/app/redux/reducer.js +++ b/common/app/redux/reducer.js @@ -30,6 +30,7 @@ export default handleActions( username: null, picture: null, points: 0, - isSignedIn: false + isSignedIn: false, + csrfToken: '' } ); diff --git a/common/app/routes/Hikes/redux/answer-saga.js b/common/app/routes/Hikes/redux/answer-saga.js index 1442778d1b5..8189f740098 100644 --- a/common/app/routes/Hikes/redux/answer-saga.js +++ b/common/app/routes/Hikes/redux/answer-saga.js @@ -21,7 +21,7 @@ function handleAnswer(getState, dispatch, next, action) { const state = getState(); const { id, name, challengeType, tests } = getCurrentHike(state); const { - app: { isSignedIn }, + app: { isSignedIn, csrfToken }, hikesApp: { currentQuestion, delta = [ 0, 0 ] @@ -76,7 +76,7 @@ function handleAnswer(getState, dispatch, next, action) { let updateUser$; if (isSignedIn) { - const body = { id, name, challengeType: +challengeType }; + const body = { id, name, challengeType: +challengeType, _csrf: csrfToken }; updateUser$ = postJSON$('/completed-challenge', body) // if post fails, will retry once .retry(3) diff --git a/common/app/routes/Hikes/redux/reducer.js b/common/app/routes/Hikes/redux/reducer.js index bb0b1300898..c48094ce753 100644 --- a/common/app/routes/Hikes/redux/reducer.js +++ b/common/app/routes/Hikes/redux/reducer.js @@ -80,11 +80,15 @@ export default handleActions( [types.goToNextHike]: state => ({ ...state, currentHike: findNextHikeName(state.hikes, state.currentHike), - shouldShowQuestions: false, - currentQuestion: 1, mouse: [ 0, 0 ] }), + [types.transitionHike]: state => ({ + ...state, + showQuestions: false, + currentQuestion: 1 + }), + [types.fetchHikesCompleted]: (state, { payload }) => { const { hikes, currentHike } = payload; diff --git a/seed/challenges/01-front-end-development-certification/basic-javascript.json b/seed/challenges/01-front-end-development-certification/basic-javascript.json index c93f526036b..579fd5c4c99 100644 --- a/seed/challenges/01-front-end-development-certification/basic-javascript.json +++ b/seed/challenges/01-front-end-development-certification/basic-javascript.json @@ -948,7 +948,7 @@ "var sampleStr = \"Alan said, \\\"Peter is learning JavaScript\\\".\";", "This signals to JavaScript that the following quote is not the end of the string, but should instead appear inside the string. So if you were to print this to the console, you would get:", "Alan said, \"Peter is learning JavaScript\".", - "

Instruction

", + "

Instructions

", "Use backslashes to assign a string to the myStr variable so that if you were to print it to the console, you would see:", "I am a \"double quoted\" string inside \"double quotes\"" ], @@ -3757,7 +3757,7 @@ "description": [ "In the casino game Blackjack, a player can gain an advantage over the house by keeping track of the relative number of high and low cards remaining in the deck. This is called Card Counting.", "Having more high cards remaining in the deck favors the player. Each card is assigned a value according to the table below. When the count is positive, the player should bet high. When the count is zero or negative, the player should bet low.", - "
Count ChangeCards
+12, 3, 4, 5, 6
07, 8, 9
-110, 'J', 'Q', 'K','A'
", + "
Count ChangeCards
+12, 3, 4, 5, 6
07, 8, 9
-110, 'J', 'Q', 'K', 'A'
", "You will write a card counting function. It will receive a card parameter and increment or decrement the global count variable according to the card's value (see table). The function will then return a string with the current count and the string \"Bet\" if the count is positive, or \"Hold\" if the count is zero or negative. The current count and the player's decision (\"Bet\" or \"Hold\") should be separated by a single space.", "Example Output
\"-3 Hold\"
\"5 Bet\"
", "Hint
Do NOT reset count to 0 when value is 7, 8, or 9." diff --git a/seed/challenges/01-front-end-development-certification/basic-ziplines.json b/seed/challenges/01-front-end-development-certification/basic-ziplines.json index 98c26941267..05d03fb5a8d 100644 --- a/seed/challenges/01-front-end-development-certification/basic-ziplines.json +++ b/seed/challenges/01-front-end-development-certification/basic-ziplines.json @@ -43,6 +43,12 @@ "A gif showing the process of adding Bootstrap to your pen.", "Click the gear in the upper left hand corner of the CSS box, then scroll down to \"Quick add\" and choose Bootstrap. Now give your h1 element the class of text-primary to change its color and prove that Bootstrap is now available.", "" + ], + [ + "//i.imgur.com/m0pWik2.gif", + "A gif showing the process of turning off auto update preview", + "When using CodePen and Ajax, it is a good idea to turn off automatic preview updating so API calls are not made too often. Too many API calls can sometimes lead to temporary blockages, and may require waiting periods before they can be used again.
To disable automatic preview updating click the \"Settings\" button at the top of the page, then click the \"Behavior\" tab. At the bottom of the page, un-check \"AUTO UPDATE PREVIEW\". Now press \"Run\" at the top of the page to update the preview, and click \"Save\".
", + "" ] ], "challengeSeed": [], diff --git a/seed/challenges/01-front-end-development-certification/gear-up-for-success.json b/seed/challenges/01-front-end-development-certification/gear-up-for-success.json index 4f68ffe7fc4..e3afeccda97 100644 --- a/seed/challenges/01-front-end-development-certification/gear-up-for-success.json +++ b/seed/challenges/01-front-end-development-certification/gear-up-for-success.json @@ -35,7 +35,16 @@ "LinkedIn reconnait Free Code Camp comme une université. Tu peux avoir accès à notre large réseau de lauréats en ajoutant Free Code Camp à la section éducation de ton profil LinkedIn. L’année d’obtention du diplôme est la prochaine année. Pour le \"Degré\", c’est \"Full Stack Web Development Certification\". Pour le \"Domaine d’études\", c’est \"Computer Software Engineering\". Puis sauvegardez les changements.", "https://www.linkedin.com/profile/edit-education?school=Free+Code+Camp" ] - ] + ], + "titleDe": "Tritt unserem LinkedIn Alumni Netzwerk bei", + "descriptionDe": [ + [ + "//i.imgur.com/vJyiXzU.gif", + "Ein GIF, das dir zeigt, wie du den unten stehenden Link anklicken kannst und welche Felder du ausfüllen musst, damit du Free Code Camp zu deinem LinkedIn Profil hinzufügst.", + "LinkedIn erkennt Free Code Camp als Universität an. Du bekommst auf unser großes Alumni Netzwerk zugriff, indem du Free Code Camp zum Ausbildungsbereich deines LinkedIn Profils hinzufügst. Setze deinen Abschlusszeitpunkt auf das nächste Jahr. In das Feld \"Abschluss\" schreibe \"Full Stack Web Development Certification\". In das Feld \"Studienfach\" schreibe \"Computer Software Engineering\". Dann klicke auf den \"Speichern\" Button.", + "https://www.linkedin.com/profile/edit-education?school=Free+Code+Camp" + ] + ] }, { "id": "560adc65cb82ac38a17513c2", @@ -70,6 +79,15 @@ "Notre communauté à son propre subreddit sur Reddit. C’est un espace où tu peux poser des questions ou partager des liens avec la communauté. Si tu n’as pas encore un compte sur Reddit, tu peux créer un dans quelque secondes – tu n’as pas besoin d’une adresse mail. Tu peux cliquer après sur le bouton \"subscribe\" pour rejoindre notre subreddit. Tu peux rejoindre d’autre subreddits listés dans la sidebar.", "https://reddit.com/r/freecodecamp" ] + ], + "titleDe": "Tritt unserem Subreddit bei", + "descriptionDe": [ + [ + "//i.imgur.com/DYjJuCG.gif", + "Ein GIF, das dir zeigt, wie du einen Reddit Account anlegen und unserem Free Code Camp Subreddit beitreten kannst.", + "Unsere Community hat ihr eigenes Subreddit auf Reddit. Das ist eine sehr praktische Art und Weise, um Fragen zu stellen und Links mit unserer gesamten Community zu teilen. Wenn du noch keinen Reddit Account hast, kannst du einen in wenigen Sekunden erstellen - du brauchst nicht mal eine E-Mail Adresse. Dann kannst du den \"subscribe\" Button klicken, um unserem Subreddit beizutreten. Wenn du willst, kannst du auch jenen Subreddits folgen, die wir in unserer Sidebar gelistet haben.", + "https://reddit.com/r/freecodecamp" + ] ] }, { @@ -123,6 +141,21 @@ "Une fois identifié, tu peux visiter la publication de Free Code Camp sur Medium et cliquer sur \"follow\". Nos campers publient plusieurs articles chaque semaine.", "https://medium.freecodecamp.com" ] + ], + "titleDe": "Lese Programmier-Nachrichten auf unserer Medium Seite", + "descriptionDe": [ + [ + "//i.imgur.com/FxSOL4a.gif", + "Ein GIF, das dir zeigt, wie du einen Medium Account anlegen kannst.", + "Unsere Community hat eine Medium Seite, auf der wir viele Artikel über Software Entwicklung veröffentlichen. Wenn du noch keinen Medium Account hast, kannst du dem Link folgen und dich entweder mit einem Account aus einem Social Network oder einer E-Mail Adresse (sie senden dir eine E-Mail, die du durchklicken kannst, um dir einen Account anzulegen.). Wenn du ein Thema ausgewählt hast, das dich interessiert, kannst du den weiteren Schritten folgen.", + "https://www.medium.com" + ], + [ + "//i.imgur.com/zhhywSX.gif", + "Ein GIF, das dir zeigt, wie du den \"follow\" Button klicken kannst, um der Free Code Camp Seite zu folgen.", + "Bist du erstmal eingeloggt, kannst du auf die Medium Seite von Free Code Camp gehen und den \"follow\" Button klicken. Unsere Camper veröffentlichen jede Woche mehrere Artikel.", + "https://medium.freecodecamp.com" + ] ] }, { @@ -158,6 +191,15 @@ "Nos campers codent fréquemment en direct sur Twitch.tv, un site de streaming populaire. Tu peux créer un compte en moins d’une minute, et suivre la chaîne de Free Code Camp. Une fois suivi, tu auras l’option de recevoir un email à chaque fois qu’un de nos campers est en direct. Et donc tu peux rejoindre plusieurs campers pour regarder et interagir sur le salon de chat. C’est une façon d’apprendre en regardant les autres coder.", "https://twitch.tv/freecodecamp" ] + ], + "titleDe": "Schaue uns auf Twitch.tv Live beim Programmieren zu", + "descriptionDe": [ + [ + "//i.imgur.com/8rtyRY1.gif", + "Ein GIF, das dir zeigt, wie du dich bei Twitch.tv anmelden und unserem Kanal folgen kannst.", + "Unsere Camper programmieren oft Live auf Twitch.tv, einer populären Streaming-Website. Du kannst in weniger als einer Minute einen Account anlegen und dann dem Kanal von Free Code Camp folgen. Wenn du dem Kanal folgst, hast du die Option E-Mail Benachrichtigungen zu bekommen, sobald einer unserer Camper live geht. Dann kannst du Dutzenden Campern folgen und ihnen beim Programmieren zusehen sowie in Chats interagieren. Das ist eine lustige und lockere Art und Weise, um von anderen Personen zu lernen, wie sie ihre Projekte umsetzen.", + "https://twitch.tv/freecodecamp" + ] ] }, { @@ -192,7 +234,16 @@ "Tu peux définir un but et t’engager à verser une somme d’argent pour aider une organisation à but non lucratif chaque mois jusqu’à atteindre ton objectif. Cela va te donner une motivation externe dans ta journée d’apprentissage, mais aussi une opportunité pour aider ces organisations. Choisi un but, et un montant à verser. Quand tu vas cliquer sur \"commit\", la page des dons de l’organisation va s’ouvrir. Cette étape est optionnel, et tu peux annuler ou arrêter ton engagement à n’importe quel instant.", "/commit" ] - ] + ], + "titleDe": "Verpflichte dich zu einem Ziel und einer gemeinnützigen Organisation", + "descriptionDe": [ + [ + "//i.imgur.com/Og1ifsn.gif", + "Ein GIF, das dir zeigt, wie du dich einem Ziel auf Free Code Camp verpflichten kannst und versprichst, eine monatliche Spende an eine gemeinnützige Organisation zu entrichten, um externe Motivation zur Erreichung deines Ziels zu haben.", + "Du kannst dir ein Ziel setzen und versprechen, einer gemeinnützigen Organisation eine monatliche Spende zu entrichten, bis du dieses Ziel erreicht hast. Das gibt dir externe Motivation in deinem Bestreben programmieren zu lernen - und eröffnet von Anfang an die Gelegenheit gemeinnützigen Organisationen zu helfen. Wähle dein Ziel und dann eine monatliche Spende. Wenn du auf \"verpflichten\" klickst, öffnet sich die Spendenseite der gemeinnützigen Organisation in einem neuen Tab. Dieser Schritt ist optional, du kannst deine Verpflichtung jederzeit ändern oder stoppen.", + "/verpflichten" + ] + ] } ] -} +} \ No newline at end of file diff --git a/seed/challenges/01-front-end-development-certification/html5-and-css.json b/seed/challenges/01-front-end-development-certification/html5-and-css.json index ff20498cb16..886b2bf8d5d 100644 --- a/seed/challenges/01-front-end-development-certification/html5-and-css.json +++ b/seed/challenges/01-front-end-development-certification/html5-and-css.json @@ -2154,7 +2154,7 @@ "tests": [ "assert($(\"input[placeholder]\").length > 0, 'message: Add a placeholder attribute text input element.');", "assert($(\"input\") && $(\"input\").attr(\"placeholder\") && $(\"input\").attr(\"placeholder\").match(/cat\\s+photo\\s+URL/gi), 'message: Set the value of your placeholder attribute to \"cat photo URL\".');", - "assert($(\"input[type=text]\").length > 0 && code.match(//gi), 'message: The finished input element should have valid syntax.');" + "assert($(\"input[type=text]\").length > 0 && code.match(/\\s]+))?)+\\s*|\\s*)\\/?>/gi), 'message: The finished input element should have valid syntax.');" ], "type": "waypoint", "titleEs": "Agrega un texto de relleno a un campo de texto", @@ -4265,7 +4265,7 @@ "assert($(\"h1\").hasClass(\"blue-text\"), 'message: Your h1 element should have the class blue-text.');", "assert($(\"h1\").attr(\"id\") === \"orange-text\", 'message: Your h1 element should have the id of orange-text.');", "assert(code.match(/h1 element should have the inline style of color: white.');", - "assert(code.match(/\\.pink-text\\s+\\{\\s+color:.*pink.*!important;\\s+\\}/gi), 'message: Your pink-text class declaration should have the !important keyword to override all other declarations.');", + "assert(code.match(/\\.pink-text\\s*?\\{\\s+color:.*pink.*!important;\\s+\\}/gi), 'message: Your pink-text class declaration should have the !important keyword to override all other declarations.');", "assert($(\"h1\").css(\"color\") === \"rgb(255, 192, 203)\", 'message: Your h1 element should be pink.');" ], "descriptionPtBR": [ diff --git a/seed/challenges/01-front-end-development-certification/intermediate-bonfires.json b/seed/challenges/01-front-end-development-certification/intermediate-bonfires.json index 7a1314cdbcc..839a72e3f10 100644 --- a/seed/challenges/01-front-end-development-certification/intermediate-bonfires.json +++ b/seed/challenges/01-front-end-development-certification/intermediate-bonfires.json @@ -550,7 +550,8 @@ "type": "bonfire", "MDNlinks": [ "RegExp", - "HTML Entities" + "HTML Entities", + "String.replace()" ], "isRequired": true, "challengeType": 5, diff --git a/seed/challenges/01-front-end-development-certification/jquery.json b/seed/challenges/01-front-end-development-certification/jquery.json index 099f4a895ec..d78d273b7e2 100644 --- a/seed/challenges/01-front-end-development-certification/jquery.json +++ b/seed/challenges/01-front-end-development-certification/jquery.json @@ -45,7 +45,7 @@ ], "tests": [ "assert(code.match(/<\\/script\\s*>/g) && code.match(//g) && code.match(/<\\/script\\s*>/g).length === code.match(//g).length, 'message: Create a script element making sure it is valid and has a closing tag.');", - "assert(code.match(/\\$\\s*?\\(\\s*?document\\)\\.ready\\s*?\\(\\s*?function\\s*?\\(\\s*?\\)\\s*?\\{/g), 'message: You should add $(document).ready(function() { to the beginning of your script element.');", + "assert(code.match(/\\$\\s*?\\(\\s*?document\\s*?\\)\\.ready\\s*?\\(\\s*?function\\s*?\\(\\s*?\\)\\s*?\\{/g), 'message: You should add $(document).ready(function() { to the beginning of your script element.');", "assert(code.match(/\\n*?\\s*?\\}\\s*?\\);/g), 'message: Close your $(document).ready(function() { function with });');" ], "type": "waypoint", @@ -200,10 +200,10 @@ "titleDe": "Elemente anhand von Klassen mit jQuery auswählen", "descriptionDe": [ "Siehst du, wie wir alle deine Button Elemente hüpfen haben lassen? Wir haben sie mit $(\"button\") ausgewählt, dann CSS-Klassen mit .addClass(\"animated bounce\"); hinzugefügt.", - "Du hast gerade jQuery's .addClass() Funktion genutzt, die dir erlaubt, Klassen zu Elemente hinzuzufügen.", + "Du hast gerade jQuery's .addClass() Funktion genutzt, die dir erlaubt, Klassen zu Elemente hinzuzufügen.", "Wähle als erstes deine div Elemente mit der Klasse well, indem du den $(\".well\") Selektor nutzt.", "Bedenke, dass du - genauso wie bei CSS-Deklarationen - einen . vor den Namen der Klasse setzen musst.", - "Dann nutze die jQuery Funktion .addClass() um die Klassen animated und shake hinzuzufügen.", + "Dann nutze die jQuery Funktion .addClass() um die Klassen animated und shake hinzuzufügen.", "Zum Beispiel könntest du alle Elemente mit der Klasse text-primary schütteln lassen, indem du folgendes zu deiner Document Ready Funktion hinzufügst:", "$(\".text-primary\").addClass(\"animated shake\");" ] @@ -344,8 +344,7 @@ "title": "Target the same element with multiple jQuery Selectors", "description": [ "Now you know three ways of targeting elements: by type: $(\"button\"), by class: $(\".btn\"), and by id $(\"#target1\").", - "Although it is possible to add multiple classes in a single .addClass() call, let's add them to the same element in three different ways.", - "Using each of the above jQuery selectors and the addClass() function:", + "Using .addClass(), add only one class at a time to the same element, three different ways:", "Add the animated class to all elements with type button.", "Add the shake class to all the buttons with class .btn.", "Add the btn-primary class to the button with id #target1." @@ -468,7 +467,7 @@ "Vamos a quitar la clase btn-default de todos nuestros elementos button." ], "titleDe": "Entferne Klassen von einem Element mit jQuery", - "descriptionDe": [ + "descriptionDe": [ "Genauso wie du Klassen mit der jQuery Funktion addClass() hinzufügen kannst, kannst du mit der jQuery Funktion removeClass() Klassen entfernen.", "So könntest du das bei einem spezifischen Button machen:", "$(\"#target2\").removeClass(\"btn-default\");", @@ -1030,7 +1029,7 @@ "Da a todos los hijos de tu elemento right-well el color naranja." ], "titleDe": "Wähle Kinder-Elemente mit jQuery aus", - "descriptionDe": [ + "descriptionDe": [ "Viele HTML-Elemente haben Kinder-Elemente, die ihre Eigenschaften von ihren Eltern-Elementen erben.", "Zum Beispiel ist jedes HTML-Element ein Kind-Element des body Elements und dein \"jQuery Playground\" h3 Element ist ein Kind-Element deines <div class=\"container-fluid\"> Elements.", "jQuery hat eine Funktion namens children(), die es dir erlaubt, auf die Kinder-Elemente des von dir ausgewählten Elements zuzugreifen.", @@ -1250,8 +1249,8 @@ "Pero vamos a hacer algo más dramático. Añade las clases animated y hinge a tu elemento body." ], "titleDe": "Mit jQuery die gesamte Seite modifizieren", - "descriptionDe": [ - "Genug mit unserem jQuery Spielplatz herumgespielt. Reißen wir ihn ein!", + "descriptionDe": [ + "Genug mit unserem jQuery Spielplatz herumgespielt. Reißen wir ihn ein!", "jQuery kann auch das body Element auswählen.", "Hier siehst du, wie wir den gesamten body Bereich ausblenden können: $(\"body\").addClass(\"animated fadeOut\");", "Aber lass uns noch etwas Dramatischeres machen. Füge die Klassen animated und hinge zu deinem body Element hinzu." diff --git a/seed/challenges/01-front-end-development-certification/object-oriented-and-functional-programming.json b/seed/challenges/01-front-end-development-certification/object-oriented-and-functional-programming.json index 8fd61d9eb8a..11a76f7d62e 100644 --- a/seed/challenges/01-front-end-development-certification/object-oriented-and-functional-programming.json +++ b/seed/challenges/01-front-end-development-certification/object-oriented-and-functional-programming.json @@ -567,7 +567,7 @@ "description": [ "You can use the split method to split a string into an array.", "split uses the argument you pass in as a delimiter to determine which points the string should be split at.", - "Here is an example of split being used to split an array at every s character:", + "Here is an example of split being used to split a string at every s character:", "var array = string.split('s');", "Use split to create an array of words from string and assign it to array." ], diff --git a/seed/challenges/03-back-end-development-certification/api-projects.json b/seed/challenges/03-back-end-development-certification/api-projects.json index 79253980ee5..d945d86e893 100644 --- a/seed/challenges/03-back-end-development-certification/api-projects.json +++ b/seed/challenges/03-back-end-development-certification/api-projects.json @@ -258,6 +258,7 @@ "User Story: I can pass a URL as a parameter and I will receive a shortened URL in the JSON response.", "User Story: If I pass an invalid URL that doesn't follow the valid http://www.example.com format, the JSON response will contain an error instead.", "User Story: When I visit that shortened URL, it will redirect me to my original link.", + "Pro Tip: Checkout this wiki article for tips on integrating MongoDB on Heroku.", "Once you've finished implementing these user stories, click the \"I've completed this challenge\" button and enter the URLs for both your GitHub repository and your live app running on Heroku.", "You can get feedback on your project from fellow campers by sharing it in our Code Review Chatroom. You can also share it on Twitter and your city's Campsite (on Facebook)." ], diff --git a/server/middlewares/global-locals.js b/server/middlewares/global-locals.js index fbd06807314..1871eb95ff9 100644 --- a/server/middlewares/global-locals.js +++ b/server/middlewares/global-locals.js @@ -3,6 +3,9 @@ export default function globalLocals() { // Make user object available in templates. res.locals.user = req.user; res.locals._csrf = req.csrfToken ? req.csrfToken() : null; + if (req.csrfToken) { + res.expose({ token: res.locals._csrf }, 'csrf'); + } next(); }; } diff --git a/server/views/account/deprecated-signin.jade b/server/views/account/deprecated-signin.jade index 57ebf22aab7..5401b419e30 100644 --- a/server/views/account/deprecated-signin.jade +++ b/server/views/account/deprecated-signin.jade @@ -15,17 +15,10 @@ block content a.btn.btn-lg.btn-block.btn-social.btn-twitter(href='/auth/twitter') i.fa.fa-twitter | Sign in with Twitter - br - p - strong IMPORTANT NOTICE - br - em These options are under deprecation and will be removed soon. - br - em After you are signed in, go to the settings page and add GitHub and/or Email as your sign in option script. $(document).ready(function() { - var method = localStorage.getItem('lastSigninMethod'), + var method = localStorage.getItem('lastSigninMethodDeprecated'), btnSelector = 'a.btn.btn-lg.btn-block.btn-social'; if (method) { try { @@ -51,6 +44,6 @@ block content $(this).removeClass('active'); obj.methodClass = $(this).attr('class').split(' ').pop(); obj.methodLink = $(this).attr('href'); - localStorage.setItem('lastSigninMethod', JSON.stringify(obj)); + localStorage.setItem('lastSigninMethodDeprecated', JSON.stringify(obj)); }); }); diff --git a/server/views/account/signin.jade b/server/views/account/signin.jade index 9ce4163c120..c6be91453d2 100644 --- a/server/views/account/signin.jade +++ b/server/views/account/signin.jade @@ -1,9 +1,9 @@ extends ../layout block content .text-center - h2 New to Free Code Camp? + h2 New to Free Code Camp? br - .button-spacer + .button-spacer | Sign up now: a.btn.btn-lg.btn-block.btn-social.btn-primary(href='/email-signup') i.fa.fa-envelope @@ -13,7 +13,7 @@ block content | Sign up with GitHub .spacer hr - .spacer + .spacer h2 Are you a returning camper? br .button-spacer @@ -41,7 +41,7 @@ block content } $.each($(btnSelector), function(i, item) { if ( - $(item).attr('href') === obj.methodLink && + $(item).text() === obj.method && $(item).hasClass(obj.methodClass) ) { $(item).addClass('active'); @@ -55,7 +55,11 @@ block content var obj = {}; $(this).removeClass('active'); obj.methodClass = $(this).attr('class').split(' ').pop(); - obj.methodLink = $(this).attr('href'); - localStorage.setItem('lastSigninMethod', JSON.stringify(obj)); + obj.method = $(this).text(); + if(obj.method === "Sign in with Email" || obj.method === "Sign in with GitHub") { + localStorage.setItem('lastSigninMethod', JSON.stringify(obj)); + } else { + localStorage.removeItem('lastSigninMethod'); + } }); });