]> Untitled Git - lemmy.git/commitdiff
Merge remote-tracking branch 'weblate/master'
authorDessalines <tyhou13@gmx.com>
Thu, 28 May 2020 18:13:44 +0000 (14:13 -0400)
committerDessalines <tyhou13@gmx.com>
Thu, 28 May 2020 18:13:44 +0000 (14:13 -0400)
docker/lemmy.hjson
server/src/api/user.rs
server/src/lib.rs
server/src/routes/nodeinfo.rs
server/src/routes/webfinger.rs
server/src/settings.rs
ui/assets/css/main.css
ui/src/components/post-form.tsx
ui/translations/en.json

index 8fe9bf554cb3b7374a3903abfe746d4a75ba5ae5..271fc78d8aee188020cd83cfb457f5ebfa2e3658 100644 (file)
@@ -23,9 +23,6 @@
   jwt_secret: "changeme"
   # The dir for the front end
   front_end_dir: "/app/dist"
-  # whether to enable activitypub federation. this feature is in alpha, do not enable in production, as might
-  # cause problems like remote instances fetching and permanently storing bad data.
-  federation_enabled: false
   # rate limits for various user actions, by user ip
   rate_limit: {
     # maximum number of messages created in interval
index c2734f5124535af70539e2709fed56b70a0ee6a1..ee57723a1e6cb35888878b8c553d14343b39ea15 100644 (file)
@@ -1,4 +1,5 @@
 use super::*;
+use crate::is_valid_username;
 use bcrypt::verify;
 
 #[derive(Serialize, Deserialize, Debug)]
@@ -261,6 +262,10 @@ impl Perform for Oper<Register> {
       return Err(APIError::err("admin_already_created").into());
     }
 
+    if !is_valid_username(&data.username) {
+      return Err(APIError::err("invalid_username").into());
+    }
+
     // Register the new user
     let user_form = UserForm {
       name: data.username.to_owned(),
index d1531d7e04e88d8eb5c4c1a40617dd680bc1fb60..ca4bedea7b09162ff79725053c40d2b89a9510c6 100644 (file)
@@ -269,11 +269,15 @@ pub fn get_ip(conn_info: &ConnectionInfo) -> String {
     .to_string()
 }
 
+pub fn is_valid_username(name: &str) -> bool {
+  VALID_USERNAME_REGEX.is_match(name)
+}
+
 #[cfg(test)]
 mod tests {
   use crate::{
-    extract_usernames, is_email_regex, is_image_content_type, remove_slurs, slur_check,
-    slurs_vec_to_str,
+    extract_usernames, is_email_regex, is_image_content_type, is_valid_username, remove_slurs,
+    slur_check, slurs_vec_to_str,
   };
 
   #[test]
@@ -291,6 +295,15 @@ mod tests {
     assert!(!is_email_regex("nada_neutho"));
   }
 
+  #[test]
+  fn test_valid_register_username() {
+    assert!(is_valid_username("Hello_98"));
+    assert!(is_valid_username("ten"));
+    assert!(!is_valid_username("Hello-98"));
+    assert!(!is_valid_username("a"));
+    assert!(!is_valid_username(""));
+  }
+
   #[test]
   fn test_slur_filter() {
     let test =
@@ -352,4 +365,5 @@ lazy_static! {
   static ref EMAIL_REGEX: Regex = Regex::new(r"^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$").unwrap();
   static ref SLUR_REGEX: Regex = RegexBuilder::new(r"(fag(g|got|tard)?|maricos?|cock\s?sucker(s|ing)?|nig(\b|g?(a|er)?(s|z)?)\b|dindu(s?)|mudslime?s?|kikes?|mongoloids?|towel\s*heads?|\bspi(c|k)s?\b|\bchinks?|niglets?|beaners?|\bnips?\b|\bcoons?\b|jungle\s*bunn(y|ies?)|jigg?aboo?s?|\bpakis?\b|rag\s*heads?|gooks?|cunts?|bitch(es|ing|y)?|puss(y|ies?)|twats?|feminazis?|whor(es?|ing)|\bslut(s|t?y)?|\btrann?(y|ies?)|ladyboy(s?)|\b(b|re|r)tard(ed)?s?)").case_insensitive(true).build().unwrap();
   static ref USERNAME_MATCHES_REGEX: Regex = Regex::new(r"/u/[a-zA-Z][0-9a-zA-Z_]*").unwrap();
+  static ref VALID_USERNAME_REGEX: Regex = Regex::new(r"^[a-zA-Z0-9_]{3,20}$").unwrap();
 }
index 9ade80283a6c8f654643e602a4d1956ca8629a65..af6fc28227056b1173dd848f530329a8b76dc3f3 100644 (file)
@@ -25,11 +25,7 @@ async fn node_info(
       Ok(site_view) => site_view,
       Err(_) => return Err(format_err!("not_found")),
     };
-    let protocols = if Settings::get().federation_enabled {
-      vec!["activitypub".to_string()]
-    } else {
-      vec![]
-    };
+    let protocols = vec![];
     Ok(NodeInfo {
       version: "2.0".to_string(),
       software: NodeInfoSoftware {
index eaab1cb8cff3a0e5b2743184993b932964c840e5..18a21efa1203dd2c1a21df6ca483f916cd55f193 100644 (file)
@@ -7,12 +7,10 @@ pub struct Params {
 }
 
 pub fn config(cfg: &mut web::ServiceConfig) {
-  if Settings::get().federation_enabled {
-    cfg.route(
-      ".well-known/webfinger",
-      web::get().to(get_webfinger_response),
-    );
-  }
+  cfg.route(
+    ".well-known/webfinger",
+    web::get().to(get_webfinger_response),
+  );
 }
 
 lazy_static! {
index 6e5667cb2ee7fbc56a9a8394c3aedae18f07efa9..9d58d5b5d8ecce52e757f536b212db383570bc68 100644 (file)
@@ -20,7 +20,6 @@ pub struct Settings {
   pub front_end_dir: String,
   pub rate_limit: RateLimitConfig,
   pub email: Option<EmailConfig>,
-  pub federation_enabled: bool,
 }
 
 #[derive(Debug, Deserialize, Clone)]
index bf249e5bf34ede4bffa34c47c1d8dd76dfa3be6d..8b51dcd931f457f5284d3ecd0c4fb166af2818bd 100644 (file)
@@ -128,10 +128,7 @@ blockquote {
 
 .new-comments {
   max-height: 50vh;
-  overflow: hidden;
-}
-
-.new-comments:hover {
+  overflow-x: hidden;
   overflow-y: auto;
 }
 
index 912d8e5896157c89ae6e9be9925b08b10b2849c0..6f1e34e01417e0e2b1a25dff00d6b2baf0e2df42 100644 (file)
@@ -194,8 +194,9 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
               <form>
                 <label
                   htmlFor="file-upload"
-                  className={`${UserService.Instance.user &&
-                    'pointer'} d-inline-block float-right text-muted font-weight-bold`}
+                  className={`${
+                    UserService.Instance.user && 'pointer'
+                  } d-inline-block float-right text-muted font-weight-bold`}
                   data-tippy-content={i18n.t('upload_image')}
                 >
                   <svg class="icon icon-inline">
@@ -288,8 +289,9 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
               )}
               {this.state.postForm.body && (
                 <button
-                  className={`mt-1 mr-2 btn btn-sm btn-secondary ${this.state
-                    .previewMode && 'active'}`}
+                  className={`mt-1 mr-2 btn btn-sm btn-secondary ${
+                    this.state.previewMode && 'active'
+                  }`}
                   onClick={linkEvent(this, this.handlePreviewToggle)}
                 >
                   {i18n.t('preview')}
@@ -328,6 +330,7 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
                   value={this.state.postForm.community_id}
                   onInput={linkEvent(this, this.handlePostCommunityChange)}
                 >
+                  <option>{i18n.t('select_a_community')}</option>
                   {this.state.communities.map(community => (
                     <option value={community.id}>{community.name}</option>
                   ))}
@@ -355,7 +358,11 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
           )}
           <div class="form-group row">
             <div class="col-sm-10">
-              <button type="submit" class="btn btn-secondary mr-2">
+              <button
+                disabled={!this.state.postForm.community_id}
+                type="submit"
+                class="btn btn-secondary mr-2"
+              >
                 {this.state.loading ? (
                   <svg class="icon icon-spinner spin">
                     <use xlinkHref="#icon-spinner"></use>
@@ -561,7 +568,7 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
         ).id;
         this.state.postForm.community_id = foundCommunityId;
       } else {
-        this.state.postForm.community_id = data.communities[0].id;
+        // By default, the null valued 'Select a Community'
       }
       this.setState(this.state);
 
@@ -571,6 +578,7 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
         let selector = new Selectr(selectId, { nativeDropdown: false });
         selector.on('selectr.select', option => {
           this.state.postForm.community_id = Number(option.value);
+          this.setState(this.state);
         });
       }
     } else if (res.op == UserOperation.CreatePost) {
index 6509bc64ef359058726480be10098f3ddf7a146e..ff28a3cf4e50690302ae4cff6f32c056df4ca476 100644 (file)
@@ -18,6 +18,7 @@
     "communities": "Communities",
     "users": "Users",
     "create_a_community": "Create a community",
+    "select_a_community": "Select a community",
     "create_community": "Create Community",
     "remove_community": "Remove Community",
     "subscribed_to_communities": "Subscribed to <1>communities</1>",
     "sponsors": "Sponsors",
     "sponsors_of_lemmy": "Sponsors of Lemmy",
     "sponsor_message":
-      "Lemmy is free, <1>open-source</1> software, meaning no advertising, monetizing, or venture capital, ever. Your donations directly support full-time development of the project. Thank you to the following people:",
+      "Lemmy is free, <1>open-source</1> software, with no advertising, monetizing, or venture capital, ever. Your donations directly support full-time development of the project. Thank you to the following people:",
     "support_on_patreon": "Support on Patreon",
     "support_on_liberapay": "Support on Liberapay",
     "support_on_open_collective": "Support on OpenCollective",
       "Couldn't find that username or email.",
     "password_incorrect": "Password incorrect.",
     "passwords_dont_match": "Passwords do not match.",
+    "invalid_username": "Invalid username.",
     "admin_already_created": "Sorry, there's already an admin.",
     "user_already_exists": "User already exists.",
     "email_already_exists": "Email already exists.",