浏览代码

Patched security issues and added unlisted rooms.

KrisVos130 9 年之前
父节点
当前提交
11f7fa1aef

+ 12 - 0
app/client/scripts/events.js

@@ -1651,6 +1651,7 @@ Template.privateRoom.events({
         var name = Session.get("privateRoomName");
         var display = $("#edit_room_display").val();
         var desc = $("#edit_room_description").val();
+        var privacy = $("#edit_room_privacy").val();
         var room = PrivateRooms.findOne({name: name});
         if (desc !== room.roomDesc) {
             Meteor.call("changePrivateRoomDescription", name, desc, function (err) {
@@ -1674,6 +1675,17 @@ Template.privateRoom.events({
                 }
             });
         }
+        if (privacy !== room.privacy) {
+            Meteor.call("changePrivateRoomPrivacy", name, privacy, function (err) {
+                if (err) {
+                    var $toastContent = $('<span><strong>Privacy not changed.</strong> ' + err.reason + '</span>');
+                    Materialize.toast($toastContent, 2000);
+                } else {
+                    var $toastContent = $('<span><strong>Privacy changed.</strong></span>');
+                    Materialize.toast($toastContent, 2000);
+                }
+            });
+        }
         $("#edit_room_modal").closeModal();
     },
     "input #volume_slider": function() {

+ 17 - 0
app/client/scripts/main.js

@@ -28,6 +28,15 @@ Deps.autorun(function() {
     Meteor.subscribe("usernames");
 });
 
+Template.registerHelper('equals', function(var1, var2) {
+        if (typeof var1 === "object") {
+            return _.isEqual(var1, var2);
+        } else {
+            return var1 === var2;
+        }
+    }
+);
+
 Handlebars.registerHelper("isAdmin", function(argument){
     if (Meteor.user() && Meteor.user().profile) {
         return Meteor.user().profile.rank === "admin";
@@ -115,6 +124,14 @@ Template.registerHelper("rtime", function(date) {
     }
 });
 
+Template.registerHelper("getSelected", function(val1, val2) {
+    if (val1 === val2) {
+        return "selected";
+    } else {
+        return "";
+    }
+});
+
 var allAlertSub = undefined;
 var YTPlayer = undefined;
 var previewEndSongTimeout = undefined;

+ 1 - 2
app/client/scripts/routes.js

@@ -193,8 +193,7 @@ Router.route("/private/:name", {
         var user = Meteor.users.findOne({});
         var room = PrivateRooms.findOne({name: this.params.name});
         if (room !== undefined) {
-            if ((room.private === true && user !== undefined && user.profile !== undefined && (user.profile.rank === "admin" ||
-                user.profile.rank === "moderator")) || room.private === false || (user !== undefined && user.profile !== undefined && room.allowed.includes(Meteor.userId())) || room.owner === Meteor.userId()) {
+            if ((room.privacy === "private" && user !== undefined && user.profile !== undefined && (user.profile.rank === "admin" || user.profile.rank === "moderator")) || (user !== undefined && user.profile !== undefined && room.allowed.includes(Meteor.userId())) || room.owner === Meteor.userId()) {
                 Session.set("type", this.params.type);
                 this.render("privateRoom");
             } else {

+ 43 - 19
app/client/templates/home.html

@@ -62,8 +62,8 @@
             </h3>
             <hr class="center-block" style="width: 99%">
             <div class="row">
-                {{#each privateRooms}}
-                    {{#if private}}
+                {{#each room in privateRooms}}
+                    {{#if equals room.privacy 'private'}}
                         {{#if isAllowedInPrivateRoom name}}
                             <div class="col s12 m6 l3">
                                 <div class="card hoverable light-blue white-text">
@@ -86,25 +86,49 @@
                             </div>
                         {{/if}}
                     {{else}}
-                        <div class="col s12 m6 l3">
-                            <div class="card hoverable">
-                                <div class="card-image waves-effect waves-block waves-light">
-                                    <a href=/private/{{name}}>
-                                        <img src='/notes.png'>
-                                        <figcaption class="caption center-align">
-                                            <h5>{{currentPrivateSong.song.title}}</h5>
-                                        </figcaption>
-                                    </a>
-                                </div>
-                                <div class="card-content">
-                                    <span class="card-title grey-text text-darken-4">{{displayName}}</span><div><span class="user-num">{{userPrivateNum}}</span> <i class="material-icons">perm_identity</i></div>
-                                    <p>{{roomDesc}}</p>
-                                </div>
-                                <div class="card-action">
-                                    <a href=/private/{{name}} class="light-blue-text text-accent-4">Join Room</a>
+                        {{#if equals room.privacy 'unlisted'}}
+                            {{#if isAllowedInPrivateRoom name}}
+                                    <div class="col s12 m6 l3">
+                                        <div class="card hoverable light-blue white-text">
+                                            <div class="card-image waves-effect waves-block waves-light">
+                                                <a href=/private/{{name}}>
+                                                    <img src='/notes.png'>
+                                                    <figcaption class="caption center-align">
+                                                        <h5>{{currentPrivateSong.song.title}}</h5>
+                                                    </figcaption>
+                                                </a>
+                                            </div>
+                                            <div class="card-content" style="overflow-x: hidden;">
+                                                <span class="card-title white-text">{{displayName}}</span><div><span class="user-num">{{userPrivateNum}}</span> <i class="material-icons">perm_identity</i></div>
+                                                <p>{{roomDesc}}</p>
+                                            </div>
+                                            <div class="card-action">
+                                                <a href=/private/{{name}} class="white-text">Join Room</a>
+                                            </div>
+                                        </div>
+                                    </div>
+                            {{/if}}
+                        {{else}}
+                            <div class="col s12 m6 l3">
+                                <div class="card hoverable">
+                                    <div class="card-image waves-effect waves-block waves-light">
+                                        <a href=/private/{{name}}>
+                                            <img src='/notes.png'>
+                                            <figcaption class="caption center-align">
+                                                <h5>{{currentPrivateSong.song.title}}</h5>
+                                            </figcaption>
+                                        </a>
+                                    </div>
+                                    <div class="card-content">
+                                        <span class="card-title grey-text text-darken-4">{{displayName}}</span><div><span class="user-num">{{userPrivateNum}}</span> <i class="material-icons">perm_identity</i></div>
+                                        <p>{{roomDesc}}</p>
+                                    </div>
+                                    <div class="card-action">
+                                        <a href=/private/{{name}} class="light-blue-text text-accent-4">Join Room</a>
+                                    </div>
                                 </div>
                             </div>
-                        </div>
+                        {{/if}}
                     {{/if}}
                 {{/each}}
             </div>

+ 8 - 0
app/client/templates/privateRoom.html

@@ -179,6 +179,14 @@
                 <input id="edit_room_display" value={{room.displayName}} type="text">
                 <label for="edit_room_display">Display Name</label>
             </div>
+            <div class="input-field col s12">
+                <select id="edit_room_privacy">
+                    <option value="public" {{getSelected 'public' room.privacy}}>Public</option>
+                    <option value="unlisted" {{getSelected 'unlisted' room.privacy}}>Unlisted</option>
+                    <option value="private" {{getSelected 'private' room.privacy}}>Private</option>
+                </select>
+                <label>Room Privacy</label>
+            </div>
             <button class="btn waves-effect waves-light" id="save_edit_room_changes">Save Changes</button>
             <button class="btn waves-effect waves-light right red" id="delete_room">Delete Room</button>
         </div>

+ 6 - 5
app/lib/schemas.js

@@ -321,10 +321,11 @@ Schemas.PrivateRoom = new SimpleSchema({
         label: "Current votes to skip current song",
         min: 0
     },
-    private: {
-        type: Boolean,
-        defaultValue: false,
-        label: "Room private or not"
+    privacy: {
+        type: String,
+        defaultValue: "private",
+        label: "Room privacy",
+        allowedValues: ["public", "unlisted", "private"]
     },
     roomDesc: {
         type: String,
@@ -355,7 +356,7 @@ Schemas.PrivateRoom = new SimpleSchema({
     },
     "owner": {
         type: String,
-        label: "Username of owner"
+        label: "User id of owner"
     },
     lastSong: {
         type: Number,

+ 18 - 1
app/server/server.js

@@ -773,7 +773,17 @@ Meteor.publish("rooms", function () {
 });
 
 Meteor.publish("private_rooms", function () {
-    return PrivateRooms.find({});
+    var userId = this.userId;
+    if (userId) {
+        var user = Meteor.users.findOne(userId);
+        if (user.profile.rank === "admin" || user.profile.rank === "moderator") {
+            return PrivateRooms.find({});
+        } else {
+            return PrivateRooms.find({$or: [{owner: userId}, {privacy: "public"}]});
+        }
+    } else {
+        return PrivateRooms.find({privacy: "public"});
+    }
 });
 
 Meteor.publish("private_playlists", function () {
@@ -926,6 +936,13 @@ Meteor.methods({
             throw new Meteor.Error(403, "Invalid permissions.");
         }
     },
+    changePrivateRoomPrivacy: function(roomName, newPrivacy) {
+        if ((isAdmin() || isPrivateRoomOwner(roomName)) && !isBanned()) {
+            PrivateRooms.update({name: roomName}, {$set: {privacy: newPrivacy}});
+        } else {
+            throw new Meteor.Error(403, "Invalid permissions.");
+        }
+    },
     addVideoToPrivatePlaylist: function(name, id) {
         if (Meteor.userId() && !isBanned()) {
             var pl = PrivatePlaylists.findOne({owner: Meteor.userId(), name: name});