+ Hire a JavaScript engineer who's experienced in HTML5,
+ Node.js, MongoDB, and Agile Development.
+
+
+
+
+
+
+
+
+
+
+
-
- Hire a JavaScript engineer who's experienced in HTML5,
- Node.js, MongoDB, and Agile Development.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- We hired our last developer out of Free Code Camp
- and couldn't be happier. Free Code Camp is now
- our go-to way to bring on pre-screened candidates
- who are enthusiastic about learning quickly and
- becoming immediately productive in their new career.
-
-
-
-
-
-
+ md={ 2 }
+ xs={ 4 }>
+
+
+
+
+
+ We hired our last developer out of Free Code Camp
+ and couldn't be happier. Free Code Camp is now
+ our go-to way to bring on pre-screened candidates
+ who are enthusiastic about learning quickly and
+ becoming immediately productive in their new career.
+
注意: もしすでに GitHub アカウントを持っていたら、あなたは \"Open link in new tab\" をクリックすることでこのステップを飛ばすことができます、新しく開かれたタブを閉じて \"go to my next step\" をクリックしてください。私たちはこの大事なステップが飛ばされてしまうのを防ぐために \"このステップを飛ばす\" ボタンは削除してあります。
",
+ "https://github.com/join"
+ ],
+ [
+ "http://i.imgur.com/hFqAEr8.gif",
+ "この gif は Github の右上にあるプロフィール画像をクリックする方法です。あなたの写真をアップロードするか、自動で生成されるピクセルアートを利用してください。そして、残りの欄に情報を入力し submit ボタンを押してください。",
+ "GitHub の右上に表示されているピクセルアートをクリックしてください、そして settings を選んでください。あなたの画像をアップロードしてください。画像はあなたの顔が写っていると良いです。他のキャンパーズの仲間たちがチャットルームであなたを見かけるようになります。住んでいる場所や名前を登録することもできます",
+ "https://github.com/settings/profile"
+ ],
+ [
+ "http://i.imgur.com/pYk0wOk.gif",
+ "この gif は GitHub のレポジトリへのスターをつける方法です。",
+ "オープンソースの Free Code Camp のレポジトリを開いてください。これは私たちボランティアチームの協力者が Free Code Camp で作っているものです。あなたは \"star\" を私たちのリポジトリに付けることができます。\"star を付けること\"は GitHub での \"いいね\" と一緒です。",
+ "https://github.com/freecodecamp/freecodecamp"
+ ],
+ [
+ "http://i.imgur.com/OmRmLB4.gif",
+ "この git は私たちのチャットルームへのリンクをクリックして、\"sign in with GitHub\" ボタンをクリックしています。そして、テキストを入力してキャンパーズの仲間へメッセージを送る方法を表しています。",
+ "あなたは Github のアカウントを持っているので、私たちのチャットルームへ GitHub を利用してログインできます。\"Hellow world!\" と言って自己紹介をし、あなたがどうやって Free Code Camp を見つけたかや何故プログラミングを学びたいのかを私たちに話してください。",
+ "https://gitter.im/FreeCodeCamp/FreeCodeCamp"
+ ],
+ [
+ "http://i.imgur.com/Ecs5XAd.gif",
+ "この gif は右上の settings ボタンを押すことで、通知の設定を変更する方法を表しています。",
+ "私たちのチャットルームはとても活発です。あなたは誰かがあなたに対してメンションを送った時にだけ通知してもらうように設定を変更した方が良いでしょう。",
+ ""
+ ],
+ [
+ "http://i.imgur.com/T0bGJPe.gif",
+ "この gif はどうやって該当するユーザに向けて個人的なメーッセージを送れるようにするかを表しています。",
+ "私たちのチャットルームは全て公開されているので、もしあなたが個人的な情報(メールアドレスや電話番号)を共有したい場合には、プライベートメッセージを利用してください。",
+ ""
+ ],
+ [
+ "http://i.imgur.com/vDTMJSh.gif",
+ "この gif はチャレンジとチャットルームへの行き来がタブを戻すことでできることを表しています。",
+ "私たちのチャレンジを通して作業をしている間はチャットルームを開いておくと良いでしょう。そうすることで、必要な時に助けを求めることができます。あなたは休憩をしているかのように他のキャンパーズと関わりを持てるでしょう。",
+ ""
+ ],
+ [
+ "http://i.imgur.com/WvQvNGN.gif",
+ "この gif は、チャットルームアプリをあなたのコンピュータに直接インストールするためにダウンロードする方法を表しています。",
+ "チャットルームのアプリをスマホや自分のパソコンにダウンロードして使うことができます。",
+ "https://gitter.im/apps"
+ ]
]
},
{
diff --git a/seed/challenges/01-front-end-development-certification/advanced-bonfires.json b/seed/challenges/01-front-end-development-certification/advanced-bonfires.json
index 197d95af9d..5fb09d2418 100644
--- a/seed/challenges/01-front-end-development-certification/advanced-bonfires.json
+++ b/seed/challenges/01-front-end-development-certification/advanced-bonfires.json
@@ -8,15 +8,10 @@
"id": "aff0395860f5d3034dc0bfc9",
"title": "Validate US Telephone Numbers",
"description": [
- "Return true if the passed string is a valid US phone number",
+ "Return true if the passed string is a valid US phone number.",
"The user may fill out the form field any way they choose as long as it is a valid US number. The following are examples of valid formats for US numbers (refer to the tests below for other variants):",
- "555-555-5555",
- "(555)555-5555",
- "(555) 555-5555",
- "555 555 5555",
- "5555555555",
- "1 555 555 5555",
- "For this challenge you will be presented with a string such as 800-692-7753 or 8oo-six427676;laskdjf. Your job is to validate or reject the US phone number based on any combination of the formats provided above. The area code is required. If the country code is provided, you must confirm that the country code is 1. Return true if the string is a valid US phone number; otherwise false.",
+ "
",
+ "For this challenge you will be presented with a string such as 800-692-7753 or 8oo-six427676;laskdjf. Your job is to validate or reject the US phone number based on any combination of the formats provided above. The area code is required. If the country code is provided, you must confirm that the country code is 1. Return true if the string is a valid US phone number; otherwise return false.",
"Remember to use Read-Search-Ask if you get stuck. Try to pair program. Write your own code."
],
"challengeSeed": [
@@ -67,12 +62,7 @@
"descriptionEs": [
"Haz que la función devuelva true (verdadero) si el texto introducido es un número válido en los EEUU.",
"El usuario debe llenar el campo del formulario de la forma que desee siempre y cuando sea un número válido en los EEUU. Los números mostrados a continuación tienen formatos válidos en los EEUU:",
- "555-555-5555",
- "(555)555-5555",
- "(555) 555-5555",
- "555 555 5555",
- "5555555555",
- "1 555 555 5555",
+ "
",
"Para esta prueba se te presentará una cadena de texto como por ejemplo: 800-692-7753 o 8oo-six427676;laskdjf. Tu trabajo consiste en validar o rechazar el número telefónico tomando como base cualquier combinación de los formatos anteriormente presentados. El código de área es requrido. Si el código de país es provisto, debes confirmar que este es 1. La función debe devolver true si la cadena de texto es un número telefónico válido en los EEUU; de lo contrario, debe devolver false.",
"Recuerda utilizar Read-Search-Ask si te sientes atascado. Intenta programar en pareja. Escribe tu propio código."
]
@@ -270,19 +260,13 @@
"id": "a19f0fbe1872186acd434d5a",
"title": "Friendly Date Ranges",
"description": [
- "Convert a date range consisting of two dates formatted as YYYY-MM-DD into a more readable format.",
- "",
- "The friendly display should use month names instead of numbers and ordinal dates instead of cardinal (\"1st\" instead of \"1\").",
- "",
+ "Convert a date range consisting of two dates formatted as YYYY-MM-DD into a more readable format.",
+ "The friendly display should use month names instead of numbers and ordinal dates instead of cardinal (1st instead of 1).",
"Do not display information that is redundant or that can be inferred by the user: if the date range ends in less than a year from when it begins, do not display the ending year. If the range ends in the same month that it begins, do not display the ending year or month.",
- "",
"Additionally, if the date range begins in the current year and ends within one year, the year should not be displayed at the beginning of the friendly range.",
- "",
- "Examples: ",
+ "Examples:",
"friendly([\"2016-07-01\", \"2016-07-04\"]) should return [\"July 1st\",\"4th\"]",
- "",
"friendly([\"2016-07-01\", \"2018-07-04\"]) should return [\"July 1st, 2016\", \"July 4th, 2018\"].",
- "",
"Remember to use Read-Search-Ask if you get stuck. Try to pair program. Write your own code."
],
"challengeSeed": [
@@ -416,9 +400,9 @@
"id": "a3f503de51cfab748ff001aa",
"title": "Pairwise",
"description": [
- "Return the sum of all indices of elements of 'arr' that can be paired with one other element to form a sum that equals the value in the second argument 'arg'. If multiple sums are possible, return the smallest sum. Once an element has been used, it cannot be reused to pair with another.",
- "For example, pairwise([1, 4, 2, 3, 0, 5], 7) should return 11 because 4, 2, 3 and 5 can be paired with each other to equal 7 and their indices (1, 2, 3, and 5) sum to 11.",
- "pairwise([1, 3, 2, 4], 4) would only equal 1, because only the first two elements can be paired to equal 4, and the first element has an index of 0!",
+ "Return the sum of all element indices of array arr that can be paired with one other element to form a sum that equals the value in the second argument arg. If multiple sums are possible, return the smallest sum. Once an element has been used, it cannot be reused to pair with another.",
+ "For example, pairwise([1, 4, 2, 3, 0, 5], 7) should return 11 because 4, 2, 3 and 5 can be paired with each other to equal 7 and their indices (1, 2, 3, and 5) sum to 11.",
+ "pairwise([1, 3, 2, 4], 4) would only return 1, because only the first two elements can be paired to equal 4, and the first element has an index of 0!",
"Remember to use Read-Search-Ask if you get stuck. Try to pair program. Write your own code."
],
"challengeSeed": [
diff --git a/seed/challenges/01-front-end-development-certification/basic-bonfires.json b/seed/challenges/01-front-end-development-certification/basic-bonfires.json
index 5b20e296ec..47cf69c07c 100644
--- a/seed/challenges/01-front-end-development-certification/basic-bonfires.json
+++ b/seed/challenges/01-front-end-development-certification/basic-bonfires.json
@@ -585,7 +585,8 @@
"tests": [
"assert.deepEqual(bouncer([7, \"ate\", \"\", false, 9]), [7, \"ate\", 9], 'message: bouncer([7, \"ate\", \"\", false, 9]) should return [7, \"ate\", 9].');",
"assert.deepEqual(bouncer([\"a\", \"b\", \"c\"]), [\"a\", \"b\", \"c\"], 'message: bouncer([\"a\", \"b\", \"c\"]) should return [\"a\", \"b\", \"c\"].');",
- "assert.deepEqual(bouncer([false, null, 0, NaN, undefined, \"\"]), [], 'message: bouncer([false, null, 0, NaN, undefined, \"\"]) should return [].');"
+ "assert.deepEqual(bouncer([false, null, 0, NaN, undefined, \"\"]), [], 'message: bouncer([false, null, 0, NaN, undefined, \"\"]) should return [].');",
+ "assert.deepEqual(bouncer([1, null, NaN, 2, undefined]), [1, 2], 'message: bouncer([1, null, NaN, 2, undefined]) should return [1, 2].');"
],
"type": "bonfire",
"MDNlinks": [
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 7d2b31f6ba..1061e5ff66 100644
--- a/seed/challenges/01-front-end-development-certification/basic-ziplines.json
+++ b/seed/challenges/01-front-end-development-certification/basic-ziplines.json
@@ -60,31 +60,31 @@
[
"http://i.imgur.com/WBetuBa.jpg",
"Un programador frustado golpeando la pantalla de su computador.",
- "Nuestros desafíos sobre algoritmos son difíciles. Algunos pueden requerir muchas horas para resolverse. Podrás frustarte, pero no te rindas.",
+ "Nuestros desafíos sobre algoritmos son difíciles. Algunos pueden requerir muchas horas para resolverse. Podrás frustarte, pero no te rindas. Se vuelve fácil con práctica.",
""
],
[
"http://i.imgur.com/p2TpOQd.jpg",
"Un tierno perro que salta sobre un obstáculo, pica el ojo y te apunta con su pata.",
- "Cuando te atasques, usa la metodología Leer-Buscar-Preguntar. No te preocupes - ya lo has entendido.",
+ "Cuando te atasques, usa la metodología Leer-Buscar-Preguntar. No te preocupes - lo tienes resuelto.",
""
],
[
"http://i.imgur.com/G1saeDt.gif",
"Un gif que muestra cómo crear una cuenta en Codepen.",
- "Para nuestros desafíos de interfaces, usaremos un editor muy famoso llamado Codepen, el cual es completamente basado en el navegador. Abre CodePen y pulsa en \"Sign up\" en la esquina superior derecha, luego ve hacia abajo donde se encuentra el plan gratuito (free plan) y pulsa en \"Sign up\". Da clic en el botón que dice \"Use info from GitHub\", luego agrega tu dirección de correo electrónico y crea una contraseña. Pulsa el botón que dice \"Sign up\". Luego, en la esquina superior derecha , da clic en \"New pen\".",
+ "Para nuestros desafíos de interfaces, usaremos un editor de código basado en el navegador que es muy famoso llamado Codepen. Pulsa en el botón de abajo \"Open link in new tab\" para abrir la página de registro de CodePen. Rellena el formulario y pulsa \"Sign up\".
Nota: Si ya tienes una cuenta de CodePen, puedes omitir este paso pulsando \"Open link in new tab\", cierra la nueva pestaña que se abre, entonces pulsa \"go to my next step\". Eliminamos nuestro botón \"skip step\" porque mucha gente solamente pulsa el botón sin realizar estos importantes pasos.
",
"http://codepen.io/signup/free"
],
[
"http://i.imgur.com/U4y9RJ1.gif",
"Un gif que muestra que puedes escribir \"hello world\" en el editor, lo cual escribirá \"hello world\" en la ventana de vista previa. También puedes mover las ventanas para cambiar su tamaño, y cambiar su orientación.",
- "En la ventana de HTML, crea un elemento h1 con el texto \"Hola mundo\". Puedes arrastrar los bordes de las ventanas para cambiar su tamaño. También puedes pulsar el botón de \"Change View\" para cambiar la orientación de las ventanas.",
+ "En la ventana de HTML, crea un elemento h1 con el texto \"Hola mundo\". Puedes arrastrar los bordes de las ventanas para cambiar su tamaño. También puedes pulsar el botón de \"Change View\" para cambiar la orientación de las ventanas.",
""
],
[
"http://i.imgur.com/G9KFQDL.gif",
"Un gif que muestra el proceso de agregar Bootstrap a tu proyecto.",
- "Pulsa el engrane en la esquina superior izquierda de la ventana de CSS, luego ve hacia abajo hasta donde dice \"Quick add\" y elige Bootstrap. Ahora dale a tu elemento h1 la clase \"text-primary\" para cambiar su color y verificar que Bootstrap está activado.",
+ "Pulsa el engrane en la esquina superior izquierda de la ventana de CSS, luego ve hacia abajo hasta donde dice \"Quick add\" y elige Bootstrap. Ahora dale a tu elemento h1 la clase \"text-primary\" para cambiar su color y verificar que Bootstrap está activado.",
""
]
],
@@ -112,13 +112,13 @@
"challengeType": 3,
"nameEs": "Construye una página Tributo",
"descriptionEs": [
- "Objetivo: Crea una aplicación con CodePen.io que funcionalmente sea similar a esta: http://codepen.io/FreeCodeCamp/full/wMQrXV",
- "Regla #1: No veas el código del proyecto de ejemplo en CodePen. Encuentra la forma de hacerlo por tu cuenta.",
- "Regla #2: Satisface las siguientes historias de usuario. Usa cualquier librería que necesites. Dale tu estilo personal.",
- "Historia de usuario: Puedo ver una página tributo con una imagen y un texto.",
- "Historia de usuario: Puedo pulsar un enlace que me llevará a un sitio web externo con mayor información sobre el tema.",
+ "Objetivo: Crea una aplicación con CodePen.io que funcionalmente sea similar a esta: http://codepen.io/FreeCodeCamp/full/wMQrXV",
+ "Regla #1: No veas el código del proyecto de ejemplo. Encuentra la forma de hacerlo por tu cuenta.",
+ "Regla #2: Satisface las siguientes historias de usuario. Usa cualquier librería que necesites. Dale tu estilo personal.",
+ "Historia de usuario: Puedo ver una página tributo con una imagen y texto.",
+ "Historia de usuario: Puedo pulsar en un enlace que me llevará a un sitio web externo con mayor información sobre el tema.",
"Recuerda utilizar Leer-Buscar-Preguntar si te sientes atascado.",
- "Cuando hayas terminado, pulsa el botón de \"I've completed this challenge\" e incluye un link a tu CodePen. ",
+ "Cuando hayas terminado, pulsa el botón \"I've completed this challenge\" e incluye un link a tu CodePen. ",
"Puedes obtener retroalimentación sobre tu proyecto por parte de otros campistas, compartiéndolo en nuestra Sala de chat para revisión de código. También puedes compartirlo en Twitter y en el campamento de tu ciudad (en Facebook)."
],
"isRequired": true
@@ -167,18 +167,18 @@
],
"nameEs": "Construye una página web para tu portafolio",
"descriptionEs": [
- "Objetivo: Crea una aplicación con CodePen.io cuya funcionalidad sea similar a la de esta: http://codepen.io/FreeCodeCamp/full/VemmoX/.",
- "Regla #1: No veas el código del proyecto de ejemplo en CodePen. Encuentra la forma de hacerlo por tu cuenta.",
- "Regla #2: Satisface las siguientes historias de usuario. Usa cualquier librería que necesites. Dale tu estilo personal.",
- "Historia de usuario: Puedo acceder a todo el contenido de la página del portafolio con sólo desplazarme en la ventana.",
- "Historia de usuario: Puedo pulsar diferentes botones que me llevarán a las páginas de las diferentes cuentas de redes sociales del creador del portafolio.",
- "Historia de usuario: Puedo ver una imagen de los diferentes proyectos que el creador del portafolio ha construido (si no has construido ningún sitio web antes, usa plantillas.)",
- "Historia de usuario opcional: Puedo navegar a las diferentes secciones de la página web pulsando botones de navegación.",
- "No te preocupes si no tienes nada que mostrar en tu portafolio todavía - en los siguientes desafíos crearás varias apps en CodePen, así que puedes regresar luego para actualizar tu portafolio.",
- "Hay varias buenas plantillas, pero para este desafío, tendrás que construir la página web de tu portafolio completamente por tu cuenta. Usar Bootstrap hará el trabajo mucho más fácil para ti.",
+ "Objetivo: Crea una aplicación con CodePen.io cuya funcionalidad sea similar a la de esta: http://codepen.io/FreeCodeCamp/full/VemmoX/.",
+ "Regla #1: No veas el código del proyecto de ejemplo. Encuentra la forma de hacerlo por tu cuenta.",
+ "Regla #2: Satisface las siguientes historias de usuario. Usa cualquier librería que necesites. Dale tu estilo personal.",
+ "Historia de usuario: Puedo acceder a todo el contenido de la página del portafolio con sólo desplazarme en la ventana.",
+ "Historia de usuario: Puedo pulsar diferentes botones que me llevarán a las páginas de las diferentes cuentas de redes sociales del creador del portafolio.",
+ "Historia de usuario: Puedo ver una imagenes en miniatura de los diferentes proyectos que el creador del portafolio ha construido (si no has construido ningún sitio web antes, usa marcadores de posición.)",
+ "Historia de usuario: Puedo navegar a las diferentes secciones de la página web pulsando botones de navegación.",
+ "No te preocupes si no tienes nada que mostrar en tu portafolio todavía - en los siguientes desafíos crearás varias aplicaciones en CodePen, así que puedes regresar luego para actualizar tu portafolio.",
+ "Hay varias plantillas buenas, pero para este desafío, tendrás que construir la página web de tu portafolio completamente por tu cuenta. Usar Bootstrap hará el trabajo mucho más fácil para ti.",
"Ten en mente que CodePen.io ignora la función Window.open(), así que si quieres abrir alguna ventana usando jQuery, necesitarás utilizar como objetivo un elemento de ancla invisible como el siguiente: <a target='_blank'>.",
- "Recuerda utilizar Read-Search-Ask si te sientes atascado.",
- "Cuando hayas terminado, pulsa el botón de \"I've completed this challenge\" e incluye un link a tu CodePen. ",
+ "Recuerda utilizar Leer-Buscar-Preguntar si te sientes atascado.",
+ "Cuando hayas terminado, pulsa el botón \"I've completed this challenge\" e incluye un link a tu CodePen. ",
"Puedes obtener retroalimentación sobre tu proyecto por parte de otros campistas, compartiéndolo en nuestra Sala de chat para revisión de código. También puedes compartirlo en Twitter y en el campamento de tu ciudad (en Facebook)."
],
"isRequired": true,
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 442db0188d..cdf4b11f29 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
@@ -22,7 +22,7 @@
"descriptionEs": [
[
"http://i.imgur.com/vJyiXzU.gif",
- "Un gif mostrando como puedes pulsar el enlace que está más adelante y llenar todos los campos necesarios para agregar los estudios de Free Code Camp a tu perfil de LinkedIn",
+ "Un gif mostrando como puedes pulsar el enlace de abajo y llenar todos los campos necesarios para agregar los estudios de Free Code Camp a tu perfil de LinkedIn",
"LinkedIn reconoce a Free Code Camp como una universidad. Puedes obtener acceso a nuestra larga red de alumnos agregando Free Code Camp a la sección de educación de tu LinkedIn. Define tu fecha de graduación para el siguiente año. En el campo \"Grado\", escribe \"Certificación de Desarrollo Web Full Stack\". En \"Campo de estudio\", escribe \"Ingeniería de Software\". Después pulsa \"Guardar Cambios\".",
"https://www.linkedin.com/profile/edit-education?school=Free+Code+Camp"
]
@@ -44,13 +44,13 @@
"releasedOn": "February 10, 2016",
"type": "Waypoint",
"challengeType": 7,
- "nameEs": "Translate",
+ "nameEs": "Unete a nuestro Subreddit",
"descriptionEs": [
[
"http://i.imgur.com/DYjJuCG.gif",
- "",
- "",
- ""
+ "Un gif mostrando como puedes crear una cuenta de Reddit y unirte a Free Code Camp subreddit.",
+ "Nuestra comunidad tiene su propio subreddit en Reddit. Esta es una manera conveniente de hacer preguntas y compartir enlaces con toda nuestra comunidad. Si aún no dispones de una cuenta de Reddit, puedes crear una en unos segundos - ni siquiera necesitas una dirección de correo electrónico. A continuación, puedes pulsar el botón \"subscribe\" para unirte a nuestro subreddit. También puedes suscribirte a otros subreddits que estan listados en la barra lateral.",
+ "https://reddit.com/r/freecodecamp"
]
]
},
@@ -76,19 +76,19 @@
"type": "Waypoint",
"challengeType": 7,
"releasedOn": "February 10, 2016",
- "nameEs": "Translate",
+ "nameEs": "Lee noticias de codificación en nuestros canal de publicaciones Medium",
"descriptionEs": [
[
"http://i.imgur.com/FxSOL4a.gif",
- "",
- "",
- ""
+ "Un gif mostrando cómo crear una cuenta en Medium.",
+ "Nuestra comunidad tiene un canal de publicaciones Medium, donde escribimos un montón de artículos sobre desarrollo de software. Si aún no dispones de una cuenta Medium, puedes seguir el enlace y registrarte usando una red social o ingresando un correo electrónico (enviarán un correo electrónico que debes abrirlo para crear tu cuenta.) Selecciona un tema de interés, puedes continuar a través de los pasos.",
+ "https://www.medium.com"
],
[
"http://i.imgur.com/zhhywSX.gif",
- "",
- "",
- ""
+ "Un gif mostrando cómo puedes pulsar el botón \"follow\" para seguir las publicaciones de Free Code Camp.",
+ "Una vez que inicias sesión, puedes ir al canal de publicaciones de Free Code Camp Medium y pulsar \"follow\". Nuestros campistas publican varios artículos cada semana.",
+ "https://medium.freecodecamp.com"
]
]
},
@@ -108,12 +108,12 @@
"type": "Waypoint",
"challengeType": 7,
"releasedOn": "February 10, 2016",
- "nameEs": "Translate",
+ "nameEs": "Miranos programar en vivo por Twitch.tv",
"descriptionEs": [
[
"http://i.imgur.com/8rtyRY1.gif",
- "",
- "",
+ "Un gif mostrando cómo resgistrarse en Twitch.tv y seguir nuestro canal.",
+ "Nuestros campistas programan en vivo con frecuencia en Twitch.tv, un sitio web popular de streaming. Puedes crear una cuenta en menos de un minuto, luego, sigue al canal de Free Code Camp. Cuando sigas al canal, verás la opción de recibir una notificación por correo electrónico cada vez que uno de nuestros campistas esté en vivo. Puedes unirte a docenas de otros campistas y verlos programar, e interactuar en una sala de chat. Esta es una manera divertida e informal de aprender observando a las personas a construir proyectos.",
"https://twitch.tv/freecodecamp"
]
]
@@ -138,7 +138,7 @@
[
"http://i.imgur.com/Og1ifsn.gif",
"Un gif mostrando como te puedes comprometer con una meta para tus estudios de Free Code Camp y prometer una donación mensual a una organización sin fines de lucro para darte motivación externa de alcanzar esa meta.",
- "Puedes poner una meta y prometer donar mensualmente a una organización sin fines de lucro hasta que alcances tu meta. Esto te dará motivación externa en tu aventura de aprender a programar, así como una oportunidad para ayudar inmediatamente a organizaciones sin fines de lucro. Elige tu meta, después elige tu donativo mensual. Cuando pulses en \"comprometerse\", la página de donación de la organización sin fines de lucro se abrirá en una nueva pestaña. Esto es completamente opcional, y puedes cambiar tu compromiso o detenerlo en cualquier momento.",
+ "Puedes poner una meta y prometer donar mensualmente a una organización sin fines de lucro hasta que alcances tu meta. Esto te dará motivación externa en tu aventura de aprender a programar, así como una oportunidad para ayudar inmediatamente a organizaciones sin fines de lucro. Elige tu meta, después elige tu donativo mensual. Cuando pulses \"commit\", la página de donación de la organización sin fines de lucro se abrirá en una nueva pestaña. Esto es completamente opcional, y puedes cambiar tu compromiso o detenerlo en cualquier momento.",
"/comprometerse"
]
]
diff --git a/seed/challenges/01-front-end-development-certification/json-apis-and-ajax.json b/seed/challenges/01-front-end-development-certification/json-apis-and-ajax.json
index eda5c05503..7fd06a6fd8 100644
--- a/seed/challenges/01-front-end-development-certification/json-apis-and-ajax.json
+++ b/seed/challenges/01-front-end-development-certification/json-apis-and-ajax.json
@@ -108,7 +108,7 @@
""
],
"tests": [
- "assert(code.match(/\\$\\s*?\\(\\s*?(?:'|\")\\.message(?:'|\")\\s*?\\)\\s*?\\.html\\s*?\\(\\s*?(?:'|\")Here\\sis\\sthe\\smessage(?:'|\")\\s*?\\);/gi), 'message: Clicking the \"Get Message\" button should give the element with the class message the text \"Here is the message\".');"
+ "assert(code.match(/\\$\\s*?\\(\\s*?(?:'|\")\\.message(?:'|\")\\s*?\\)\\s*?(\\.html|\\.text)\\s*?\\(\\s*?(?:'|\")Here\\sis\\sthe\\smessage(?:'|\")\\s*?\\);/gi), 'message: Clicking the \"Get Message\" button should give the element with the class message the text \"Here is the message\".');"
],
"type": "waypoint",
"challengeType": 0,
diff --git a/seed/challenges/04-video-challenges/computer-basics.json b/seed/challenges/04-video-challenges/computer-basics.json
index ed7b73d22d..689bd0eb16 100644
--- a/seed/challenges/04-video-challenges/computer-basics.json
+++ b/seed/challenges/04-video-challenges/computer-basics.json
@@ -1110,7 +1110,37 @@
]
],
"type": "hike",
- "challengeType": 6
+ "challengeType": 6,
+ "nameEs": "Seguridad en los computadores",
+ "descriptionEs": [
+ "Lo fundamental de la seguridad en los computadores y cómo proteger su información.",
+ "Echemos una mirada a la seguridad en los computadores.",
+ "De lo primero que vamos a hablar es de algo conocido como ataque diccionario que se dirige a sus claves.",
+ "Cuando tu creas una clave, algunos lugares de internet te exigen claves muy específicas y complejas, las cuales con frecuencia no son tan necesarias.",
+ "El tipo de ataque que ellos quieren evitar son los llamados ataques diccionario.",
+ "Los ataques diccionario están programados para probar todas las palabras de un diccionario o todas las claves mas usuales, para una gran cantidad de nombres de usuario, registradas en sus propias bases de datos. ",
+ "Su tu clave es Canguro, probablemente podrá ser descubierta ya que es una palabra simple.",
+ "Aunque algunas claves no son tan sencillas como la anterior, esto tampoco importa.",
+ "Ellos atacan tal cantidad de cuentas que solo necesitan unas pocas claves que sean sencillas.",
+ "Cundo se crea una clave, tú usas letras mayúsculas, minúsculas, números y símbolos, pero una de las formas más eficientes es seleccionar números y letras al azar (ejemplo: canguroSyCA67).",
+ "Por lo tanto mantente lejos de los números seguidos.",
+ "Suplantación es otra forma de ataque del cual debes estar pendiente. Son correos o páginas web que simulan sitios seguros y engañan a las personas para obtener su información personlal. Son sitios que no están conectados a donde dicen que estan.",
+ "En general hay dos formas de resguardarse de estos ataques: verificar la dirección web de la página y abrir la dirección de la página web, en otro navegador para poder comprobar si corresponde con el sitio del que dicen que procede.",
+ "Ahora hablemos sobre cifrado y HTTPS",
+ "Si te encuentras comprando en una página de internet de una tienda muy prestigiosa y necesitas dar los datos de tu tarjeta de crédito es muy razonable que sospeches que alguien puede estar viendo y copiando esta información.",
+ "Es imprescindible que te fijes que la dirección de esta página web, en tu navegador, comienza con letras verdes y con HTTPS en vez de comenzar con solo HTTP.",
+ "Esto significa que el sitio por el que estás enviando esta información, la envía en forma codificada",
+ "En general, asegúrate que la página sea HTTPS si necesita escribir información privada o importante.",
+ "Otras recomendaciones importantes: no uses la misma clave para diferentes cuentas importantes",
+ "Si el sitio que usas ha sido vulnerado, tu clave puede estar comprometida independientemente de su fortaleza.",
+ "Tampoco descargues archivos desconocidos.",
+ "Se precavido si no reconoces archivos de tipo .pdf, .txt, .jpg.",
+ "Algunos de estos archivos pueden ser muy potentes e incluso correr dentro de tu computador.",
+ "Por último, mantén tu software actualizado, en especial el software que interactúa con internet.",
+ "Una de las formas en que se puede comprometer tu información es cuando los 'los chicos malos' encuentran huecos en las versiones viejas de los programas",
+ "Estos defectos se corrigen en las versiones nuevas, por lo que evitarás problemas si mantienes el software actualizado.",
+ "Estas son algunas cosas muy básicas que debes saber acerca de cómo proteger la información de tu computador."
+ ]
}
]
}
diff --git a/server/boot/a-extendUser.js b/server/boot/a-extendUser.js
index b212550a8a..e43cdeff2b 100644
--- a/server/boot/a-extendUser.js
+++ b/server/boot/a-extendUser.js
@@ -1,7 +1,7 @@
import { Observable } from 'rx';
import debugFactory from 'debug';
-const debug = debugFactory('freecc:user:remote');
+const debug = debugFactory('fcc:user:remote');
function destroyAllRelated(id, Model) {
return Observable.fromNodeCallback(
@@ -21,7 +21,7 @@ module.exports = function(app) {
if (!id) {
return next();
}
- Observable.combineLatest(
+ return Observable.combineLatest(
destroyAllRelated(id, UserIdentity),
destroyAllRelated(id, UserCredential),
function(identData, credData) {
@@ -30,19 +30,20 @@ module.exports = function(app) {
credData: credData
};
}
- ).subscribe(
- function(data) {
- debug('deleted', data);
- },
- function(err) {
- debug('error deleting user %s stuff', id, err);
- next(err);
- },
- function() {
- debug('user stuff deleted for user %s', id);
- next();
- }
- );
+ )
+ .subscribe(
+ function(data) {
+ debug('deleted', data);
+ },
+ function(err) {
+ debug('error deleting user %s stuff', id, err);
+ next(err);
+ },
+ function() {
+ debug('user stuff deleted for user %s', id);
+ next();
+ }
+ );
});
// set email varified false on user email signup
@@ -82,15 +83,15 @@ module.exports = function(app) {
};
debug('sending welcome email');
- Email.send(mailOptions, function(err) {
+ return Email.send(mailOptions, function(err) {
if (err) { return next(err); }
- req.logIn(user, function(err) {
+ return req.logIn(user, function(err) {
if (err) { return next(err); }
req.flash('success', {
msg: [ "Welcome to Free Code Camp! We've created your account." ]
});
- res.redirect(redirect);
+ return res.redirect(redirect);
});
});
});
diff --git a/server/boot/a-extendUserIdent.js b/server/boot/a-extendUserIdent.js
index 932965f3ff..3b8cbfea54 100644
--- a/server/boot/a-extendUserIdent.js
+++ b/server/boot/a-extendUserIdent.js
@@ -1,4 +1,4 @@
-import{ Observable } from 'rx';
+import { Observable } from 'rx';
import debugFactory from 'debug';
import dedent from 'dedent';
diff --git a/server/boot/a-react.js b/server/boot/a-react.js
index e3d7711839..5d13e39b99 100644
--- a/server/boot/a-react.js
+++ b/server/boot/a-react.js
@@ -1,14 +1,13 @@
import React from 'react';
-import { RoutingContext } from 'react-router';
-import Fetchr from 'fetchr';
-import { createLocation } from 'history';
-import debugFactory from 'debug';
-import { dehydrate } from 'thundercats';
-import { renderToString$ } from 'thundercats-react';
+import { RouterContext } from 'react-router';
+import debug from 'debug';
+
+import renderToString from '../../common/app/utils/render-to-string';
+import provideStore from '../../common/app/provide-store';
import app$ from '../../common/app';
-const debug = debugFactory('freecc:react-server');
+const log = debug('fcc:react-server');
// add routes here as they slowly get reactified
// remove their individual controllers
@@ -38,52 +37,43 @@ export default function reactSubRouter(app) {
app.use(router);
function serveReactApp(req, res, next) {
- const services = new Fetchr({ req });
- const location = createLocation(req.path);
-
- // returns a router wrapped app
- app$({ location })
+ const serviceOptions = { req };
+ app$({
+ location: req.path,
+ serviceOptions
+ })
// if react-router does not find a route send down the chain
- .filter(function({ props }) {
+ .filter(({ redirect, props }) => {
+ if (!props && redirect) {
+ res.redirect(redirect.pathname + redirect.search);
+ }
if (!props) {
- debug('react tried to find %s but got 404', location.pathname);
+ log(`react tried to find ${location.pathname} but got 404`);
return next();
}
return !!props;
})
- .flatMap(function({ props, AppCat }) {
- const cat = AppCat(null, services);
- debug('render react markup and pre-fetch data');
- const store = cat.getStore('appStore');
+ .flatMap(({ props, store }) => {
+ log('render react markup and pre-fetch data');
- // primes store to observe action changes
- // cleaned up by cat.dispose further down
- store.subscribe(() => {});
-
- return renderToString$(
- cat,
- React.createElement(RoutingContext, props)
+ return renderToString(
+ provideStore(React.createElement(RouterContext, props), store)
)
- .flatMap(
- dehydrate(cat),
- ({ markup }, data) => ({ markup, data, cat })
- );
+ .map(({ markup }) => ({ markup, store }));
})
- .flatMap(function({ data, markup, cat }) {
- debug('react markup rendered, data fetched');
- cat.dispose();
- const { title } = data.AppStore;
- res.expose(data, 'data');
+ .flatMap(function({ markup, store }) {
+ log('react markup rendered, data fetched');
+ const state = store.getState();
+ const { title } = state.app.title;
+ res.expose(state, 'data');
return res.render$(
'layout-react',
{ markup, title }
);
})
+ .doOnNext(markup => res.send(markup))
.subscribe(
- function(markup) {
- debug('html rendered and ready to send');
- res.send(markup);
- },
+ () => log('html rendered and ready to send'),
next
);
}
diff --git a/server/boot/certificate.js b/server/boot/certificate.js
index e4082e5f74..6775edd3a0 100644
--- a/server/boot/certificate.js
+++ b/server/boot/certificate.js
@@ -22,7 +22,7 @@ import {
import certTypes from '../utils/certTypes.json';
-const log = debug('freecc:certification');
+const log = debug('fcc:certification');
const sendMessageToNonUser = ifNoUserSend(
'must be logged in to complete.'
);
diff --git a/server/boot/challenge.js b/server/boot/challenge.js
index 957483f279..d793b9fbfd 100644
--- a/server/boot/challenge.js
+++ b/server/boot/challenge.js
@@ -26,7 +26,7 @@ import badIdMap from '../utils/bad-id-map';
const isDev = process.env.NODE_ENV !== 'production';
const isBeta = !!process.env.BETA;
-const log = debug('freecc:challenges');
+const log = debug('fcc:challenges');
const challengesRegex = /^(bonfire|waypoint|zipline|basejump|checkpoint)/i;
const challengeView = {
0: 'challenges/showHTML',
@@ -120,6 +120,7 @@ function shouldShowNew(element, block) {
}, 0);
return newCount / block.length * 100 === 100;
}
+ return null;
}
// meant to be used with a filter method
@@ -516,7 +517,7 @@ module.exports = function(app) {
if (data.id) {
res.cookie('currentChallengeId', data.id);
}
- res.render(view, data);
+ return res.render(view, data);
},
next,
function() {}
@@ -525,14 +526,12 @@ module.exports = function(app) {
function completedChallenge(req, res, next) {
req.checkBody('id', 'id must be a ObjectId').isMongoId();
-
req.checkBody('name', 'name must be at least 3 characters')
.isString()
.isLength({ min: 3 });
-
req.checkBody('challengeType', 'challengeType must be an integer')
- .isNumber()
- .isInt();
+ .isNumber();
+
const type = accepts(req).type('html', 'json', 'text');
const errors = req.validationErrors(true);
@@ -585,7 +584,7 @@ module.exports = function(app) {
alreadyCompleted
});
}
- res.sendStatus(200);
+ return res.sendStatus(200);
}
);
}
@@ -597,8 +596,7 @@ module.exports = function(app) {
.isString()
.isLength({ min: 3 });
req.checkBody('challengeType', 'must be a number')
- .isNumber()
- .isInt();
+ .isNumber();
req.checkBody('solution', 'solution must be a url').isURL();
const errors = req.validationErrors(true);
@@ -652,7 +650,7 @@ module.exports = function(app) {
user.progressTimestamps.length + 1
});
}
- res.status(200).send(true);
+ return res.status(200).send(true);
})
.subscribe(() => {}, next);
}
diff --git a/server/boot/commit.js b/server/boot/commit.js
index 8d5805ee2a..5bb00e7ce7 100644
--- a/server/boot/commit.js
+++ b/server/boot/commit.js
@@ -34,7 +34,7 @@ const sendNonUserToCommit = ifNoUserRedirectTo(
'info'
);
-const debug = debugFactory('freecc:commit');
+const debug = debugFactory('fcc:commit');
function findNonprofit(name) {
let nonprofit;
@@ -217,7 +217,7 @@ export default function commit(app) {
})
.subscribe(
pledge => {
- let msg = `You have successfully stopped your pledge.`;
+ let msg = 'You have successfully stopped your pledge.';
if (!pledge) {
msg = `No pledge found for user ${user.username}.`;
}
diff --git a/server/boot/home.js b/server/boot/home.js
index 8d8a2be441..a4e01ece1e 100644
--- a/server/boot/home.js
+++ b/server/boot/home.js
@@ -14,9 +14,9 @@ module.exports = function(app) {
return next();
}
req.user.picture = defaultProfileImage;
- req.user.save(function(err) {
+ return req.user.save(function(err) {
if (err) { return next(err); }
- next();
+ return next();
});
}
@@ -24,6 +24,6 @@ module.exports = function(app) {
if (req.user) {
return res.redirect('/challenges/current-challenge');
}
- res.render('home', { title: message });
+ return res.render('home', { title: message });
}
};
diff --git a/server/boot/randomAPIs.js b/server/boot/randomAPIs.js
index 8daa663b3a..62e4438fad 100644
--- a/server/boot/randomAPIs.js
+++ b/server/boot/randomAPIs.js
@@ -2,7 +2,7 @@ var Rx = require('rx'),
async = require('async'),
moment = require('moment'),
request = require('request'),
- debug = require('debug')('freecc:cntr:resources'),
+ debug = require('debug')('fcc:cntr:resources'),
constantStrings = require('../utils/constantStrings.json'),
labs = require('../resources/labs.json'),
testimonials = require('../resources/testimonials.json'),
@@ -145,7 +145,7 @@ module.exports = function(app) {
if (err) {
return next(err);
}
- process.nextTick(function() {
+ return process.nextTick(function() {
res.header('Content-Type', 'application/xml');
res.render('resources/sitemap', {
appUrl: appUrl,
@@ -227,14 +227,18 @@ module.exports = function(app) {
}
function confirmStickers(req, res) {
- req.flash('success', { msg: 'Thank you for supporting our community! You should receive your stickers in the ' +
- 'mail soon!'});
- res.redirect('/shop');
+ req.flash('success', {
+ msg: 'Thank you for supporting our community! You should receive ' +
+ 'your stickers in the mail soon!'
+ });
+ res.redirect('/shop');
}
function cancelStickers(req, res) {
- req.flash('info', { msg: 'You\'ve cancelled your purchase of our stickers. You can '
- + 'support our community any time by buying some.'});
+ req.flash('info', {
+ msg: 'You\'ve cancelled your purchase of our stickers. You can ' +
+ 'support our community any time by buying some.'
+ });
res.redirect('/shop');
}
function submitCatPhoto(req, res) {
@@ -280,18 +284,14 @@ module.exports = function(app) {
function unsubscribe(req, res, next) {
User.findOne({ where: { email: req.params.email } }, function(err, user) {
if (user) {
- if (err) {
- return next(err);
- }
+ if (err) { return next(err); }
user.sendMonthlyEmail = false;
- user.save(function() {
- if (err) {
- return next(err);
- }
- res.redirect('/unsubscribed');
+ return user.save(function() {
+ if (err) { return next(err); }
+ return res.redirect('/unsubscribed');
});
} else {
- res.redirect('/unsubscribed');
+ return res.redirect('/unsubscribed');
}
});
}
@@ -330,7 +330,7 @@ module.exports = function(app) {
Object.keys(JSON.parse(pulls)).length :
'Can\'t connect to github';
- request(
+ return request(
[
'https://api.github.com/repos/freecodecamp/',
'freecodecamp/issues?client_id=',
@@ -344,7 +344,7 @@ module.exports = function(app) {
issues = ((pulls === parseInt(pulls, 10)) && issues) ?
Object.keys(JSON.parse(issues)).length - pulls :
"Can't connect to GitHub";
- res.send({
+ return res.send({
issues: issues,
pulls: pulls
});
@@ -364,7 +364,7 @@ module.exports = function(app) {
(JSON.parse(trello)) :
'Can\'t connect to to Trello';
- res.end(JSON.stringify(trello));
+ return res.end(JSON.stringify(trello));
});
}
@@ -379,7 +379,7 @@ module.exports = function(app) {
blog = (status && status.statusCode === 200) ?
JSON.parse(blog) :
'Can\'t connect to Blogger';
- res.end(JSON.stringify(blog));
+ return res.end(JSON.stringify(blog));
}
);
}
diff --git a/server/boot/story.js b/server/boot/story.js
index 516ce9e268..8857290bc0 100755
--- a/server/boot/story.js
+++ b/server/boot/story.js
@@ -2,7 +2,7 @@ var Rx = require('rx'),
assign = require('object.assign'),
sanitizeHtml = require('sanitize-html'),
moment = require('moment'),
- debug = require('debug')('freecc:cntr:story'),
+ debug = require('debug')('fcc:cntr:story'),
utils = require('../utils'),
observeMethod = require('../utils/rx').observeMethod,
saveUser = require('../utils/rx').saveUser,
@@ -207,7 +207,7 @@ module.exports = function(app) {
return upvote.upVotedByUsername === username;
});
- res.render('stories/index', {
+ return res.render('stories/index', {
title: story.headline,
link: story.link,
originalStoryLink: dashedName,
@@ -357,7 +357,7 @@ module.exports = function(app) {
url = 'http://' + url;
}
- findStory({ where: { link: url } })
+ return findStory({ where: { link: url } })
.map(function(stories) {
if (stories.length) {
return {
diff --git a/server/boot/user.js b/server/boot/user.js
index bfb0ca6afa..8af387b323 100644
--- a/server/boot/user.js
+++ b/server/boot/user.js
@@ -19,7 +19,7 @@ import {
calcLongestStreak
} from '../utils/user-stats';
-const debug = debugFactory('freecc:boot:user');
+const debug = debugFactory('fcc:boot:user');
const sendNonUserToMap = ifNoUserRedirectTo('/map');
const certIds = {
[certTypes.frontEnd]: frontEndChallengeId,
@@ -195,7 +195,7 @@ module.exports = function(app) {
if (req.user) {
return res.redirect('/');
}
- res.render('account/signin', {
+ return res.render('account/signin', {
title: 'Sign in to Free Code Camp using a Social Media Account'
});
}
@@ -209,7 +209,7 @@ module.exports = function(app) {
if (req.user) {
return res.redirect('/');
}
- res.render('account/email-signin', {
+ return res.render('account/email-signin', {
title: 'Sign in to Free Code Camp using your Email Address'
});
}
@@ -218,7 +218,7 @@ module.exports = function(app) {
if (req.user) {
return res.redirect('/');
}
- res.render('account/email-signup', {
+ return res.render('account/email-signup', {
title: 'Sign up for Free Code Camp using your Email Address'
});
}
@@ -387,7 +387,7 @@ module.exports = function(app) {
req.flash('errors', {
msg: `Looks like user ${username} is not ${certText[certType]}`
});
- res.redirect('back');
+ return res.redirect('back');
},
next
);
@@ -406,7 +406,7 @@ module.exports = function(app) {
section at the bottom of this page.
`
});
- res.redirect('/' + req.user.username);
+ return res.redirect('/' + req.user.username);
});
}
req.user.isLocked = true;
@@ -420,7 +420,7 @@ module.exports = function(app) {
section at the bottom of this page.
`
});
- res.redirect('/' + req.user.username);
+ return res.redirect('/' + req.user.username);
});
}
@@ -429,7 +429,7 @@ module.exports = function(app) {
if (err) { return next(err); }
req.logout();
req.flash('info', { msg: 'Your account has been deleted.' });
- res.redirect('/');
+ return res.redirect('/');
});
}
@@ -438,7 +438,7 @@ module.exports = function(app) {
req.flash('errors', { msg: 'access token invalid' });
return res.render('account/forgot');
}
- res.render('account/reset', {
+ return res.render('account/reset', {
title: 'Reset your Password',
accessToken: req.accessToken.id
});
@@ -453,14 +453,14 @@ module.exports = function(app) {
return res.redirect('back');
}
- User.findById(req.accessToken.userId, function(err, user) {
- if (err) { return next(err); }
- user.updateAttribute('password', password, function(err) {
+ return User.findById(req.accessToken.userId, function(err, user) {
if (err) { return next(err); }
+ return user.updateAttribute('password', password, function(err) {
+ if (err) { return next(err); }
debug('password reset processed successfully');
req.flash('info', { msg: 'password reset processed successfully' });
- res.redirect('/');
+ return res.redirect('/');
});
});
}
@@ -469,7 +469,7 @@ module.exports = function(app) {
if (req.isAuthenticated()) {
return res.redirect('/');
}
- res.render('account/forgot', {
+ return res.render('account/forgot', {
title: 'Forgot Password'
});
}
@@ -483,7 +483,7 @@ module.exports = function(app) {
return res.redirect('/forgot');
}
- User.resetPassword({
+ return User.resetPassword({
email: email
}, function(err) {
if (err) {
@@ -496,7 +496,7 @@ module.exports = function(app) {
email +
' with further instructions.'
});
- res.render('account/forgot');
+ return res.render('account/forgot');
});
}
@@ -507,7 +507,7 @@ module.exports = function(app) {
if (err) { return next(err); }
req.flash('success', { msg: 'Thanks for voting!' });
- res.redirect('/map');
+ return res.redirect('/map');
});
} else {
req.flash('error', { msg: 'You must be signed in to vote.' });
@@ -522,7 +522,7 @@ module.exports = function(app) {
if (err) { return next(err); }
req.flash('success', { msg: 'Thanks for voting!' });
- res.redirect('/map');
+ return res.redirect('/map');
});
} else {
req.flash('error', {msg: 'You must be signed in to vote.'});
diff --git a/server/middlewares/add-return-to.js b/server/middlewares/add-return-to.js
index 8a5b2b0dc0..0d25940e6b 100644
--- a/server/middlewares/add-return-to.js
+++ b/server/middlewares/add-return-to.js
@@ -36,8 +36,9 @@ export default function addReturnToUrl() {
) {
return next();
}
- req.session.returnTo = req.originalUrl === '/map-aside'
- ? '/map' : req.originalUrl;
- next();
+ req.session.returnTo = req.originalUrl === '/map-aside' ?
+ '/map' :
+ req.originalUrl;
+ return next();
};
}
diff --git a/server/middlewares/revision-helpers.js b/server/middlewares/revision-helpers.js
index 3f84fe9c90..23012280c3 100644
--- a/server/middlewares/revision-helpers.js
+++ b/server/middlewares/revision-helpers.js
@@ -26,6 +26,6 @@ export default function({ globalPrepend = '' } = {}) {
// in production we take use the initially loaded manifest
// since this should not change in production
res.locals.rev = boundRev;
- next();
+ return next();
};
}
diff --git a/server/services/hikes.js b/server/services/hikes.js
index bd4a6810e1..5a99bb5b3b 100644
--- a/server/services/hikes.js
+++ b/server/services/hikes.js
@@ -1,23 +1,23 @@
import debugFactory from 'debug';
import assign from 'object.assign';
-const debug = debugFactory('freecc:services:hikes');
+const debug = debugFactory('fcc:services:hikes');
export default function hikesService(app) {
const Challenge = app.models.Challenge;
return {
name: 'hikes',
- read: (req, resource, params, config, cb) => {
+ read: (req, resource, { dashedName } = {}, config, cb) => {
const query = {
where: { challengeType: '6' },
order: ['order ASC', 'suborder ASC' ]
};
- debug('params', params);
- if (params) {
+ debug('dashedName', dashedName);
+ if (dashedName) {
assign(query.where, {
- dashedName: { like: params.dashedName, options: 'i' }
+ dashedName: { like: dashedName, options: 'i' }
});
}
debug('query', query);
@@ -25,7 +25,7 @@ export default function hikesService(app) {
if (err) {
return cb(err);
}
- cb(null, hikes);
+ return cb(null, hikes.map(hike => hike.toJSON()));
});
}
};
diff --git a/server/services/job.js b/server/services/job.js
index 48da7f4605..ad0bd35cea 100644
--- a/server/services/job.js
+++ b/server/services/job.js
@@ -22,18 +22,20 @@ export default function getJobServices(app) {
isApproved: false
});
- Job.create(job, (err, savedJob) => {
- cb(err, savedJob);
+ return Job.create(job, (err, savedJob) => {
+ cb(err, savedJob.toJSON());
});
},
read(req, resource, params, config, cb) {
const id = params ? params.id : null;
if (id) {
- return Job.findById(id, cb);
+ return Job.findById(id)
+ .then(job => cb(null, job.toJSON()))
+ .catch(cb);
}
- Job.find(whereFilt, (err, jobs) => {
- cb(err, jobs);
- });
+ return Job.find(whereFilt)
+ .then(jobs => cb(null, jobs.map(job => job.toJSON())))
+ .catch(cb);
}
};
}
diff --git a/server/services/user.js b/server/services/user.js
index 3fa4dc40c1..a2816e818c 100644
--- a/server/services/user.js
+++ b/server/services/user.js
@@ -2,7 +2,7 @@ import debugFactory from 'debug';
import assign from 'object.assign';
const censor = '**********************:P********';
-const debug = debugFactory('freecc:services:user');
+const debug = debugFactory('fcc:services:user');
const protectedUserFields = {
id: censor,
password: censor,
diff --git a/server/utils/commit.js b/server/utils/commit.js
index 02ce7ab5dc..0a9474c40a 100644
--- a/server/utils/commit.js
+++ b/server/utils/commit.js
@@ -3,7 +3,7 @@ import debugFactory from 'debug';
import { Observable } from 'rx';
import commitGoals from './commit-goals.json';
-const debug = debugFactory('freecc:utils/commit');
+const debug = debugFactory('fcc:utils/commit');
export { commitGoals };
diff --git a/server/utils/index.js b/server/utils/index.js
index d830b55850..9efdc7ae9d 100644
--- a/server/utils/index.js
+++ b/server/utils/index.js
@@ -75,7 +75,7 @@ module.exports = {
result.image = urlImage;
result.description = description;
- callback(null, result);
+ return callback(null, result);
});
},
diff --git a/server/utils/rx.js b/server/utils/rx.js
index 68086d2563..891d24e9f3 100644
--- a/server/utils/rx.js
+++ b/server/utils/rx.js
@@ -1,7 +1,7 @@
import Rx from 'rx';
import debugFactory from 'debug';
-const debug = debugFactory('freecc:rxUtils');
+const debug = debugFactory('fcc:rxUtils');
export function saveInstance(instance) {
return new Rx.Observable.create(function(observer) {
@@ -10,13 +10,13 @@ export function saveInstance(instance) {
observer.onNext();
return observer.onCompleted();
}
- instance.save(function(err, savedInstance) {
+ return instance.save(function(err, savedInstance) {
if (err) {
return observer.onError(err);
}
debug('instance saved');
observer.onNext(savedInstance);
- observer.onCompleted();
+ return observer.onCompleted();
});
});
}