Просмотр исходного кода

Merge branch 'master' into ja-turn-off-registration

James Allen 9 лет назад
Родитель
Сommit
310aa1d49d

+ 27 - 5
services/web/app/coffee/Features/Project/ProjectController.coffee

@@ -24,6 +24,7 @@ AnalyticsManager = require "../Analytics/AnalyticsManager"
 Sources = require "../Authorization/Sources"
 TokenAccessHandler = require '../TokenAccess/TokenAccessHandler'
 CollaboratorsHandler = require '../Collaborators/CollaboratorsHandler'
+Modules = require '../../infrastructure/Modules'
 crypto = require 'crypto'
 
 module.exports = ProjectController =
@@ -148,6 +149,11 @@ module.exports = ProjectController =
 				NotificationsHandler.getUserNotifications user_id, cb
 			projects: (cb)->
 				ProjectGetter.findAllUsersProjects user_id, 'name lastUpdated publicAccesLevel archived owner_ref tokens', cb
+			v1Projects: (cb) ->
+				Modules.hooks.fire "findAllV1Projects", user_id, (error, projects = []) ->
+					if error? and error.message == 'No V1 connection'
+						return cb(null, projects: [], tags: [], noConnection: true)
+					return cb(error, projects[0]) # hooks.fire returns an array of results, only need first
 			hasSubscription: (cb)->
 				LimitationsManager.userHasSubscriptionOrIsGroupMember currentUser, cb
 			user: (cb) ->
@@ -157,11 +163,12 @@ module.exports = ProjectController =
 					logger.err err:err, "error getting data for project list page"
 					return next(err)
 				logger.log results:results, user_id:user_id, "rendering project list"
-				tags = results.tags[0]
+				v1Tags = results.v1Projects?.tags or []
+				tags = results.tags[0].concat(v1Tags)
 				notifications = require("underscore").map results.notifications, (notification)->
 					notification.html = req.i18n.translate(notification.templateKey, notification.messageOpts)
 					return notification
-				projects = ProjectController._buildProjectList results.projects
+				projects = ProjectController._buildProjectList results.projects, results.v1Projects?.projects
 				user = results.user
 				ProjectController._injectProjectOwners projects, (error, projects) ->
 					return next(error) if error?
@@ -173,6 +180,8 @@ module.exports = ProjectController =
 						notifications: notifications or []
 						user: user
 						hasSubscription: results.hasSubscription[0]
+						isShowingV1Projects: results.v1Projects?
+						noV1Connection: results.v1Projects?.noConnection
 					}
 
 					if Settings?.algolia?.app_id? and Settings?.algolia?.read_only_api_key?
@@ -280,7 +289,7 @@ module.exports = ProjectController =
 				# Extract data from user's ObjectId
 				timestamp = parseInt(user_id.toString().substring(0, 8), 16)
 
-				rolloutPercentage = 5 # Percentage of users to roll out to
+				rolloutPercentage = 10 # Percentage of users to roll out to
 				if !ProjectController._isInPercentageRollout('autocompile', user_id, rolloutPercentage)
 					# Don't show if user is not part of roll out
 					return cb(null, { enabled: false, showOnboarding: false })
@@ -333,7 +342,7 @@ module.exports = ProjectController =
 			enableTokenAccessUI = ProjectController._isInPercentageRollout(
 				'linksharing',
 				project.owner_ref,
-				40
+				100
 			)
 			showLinkSharingOnboarding = enableTokenAccessUI && results.couldShowLinkSharingOnboarding
 			AuthorizationManager.getPrivilegeLevelForProject user_id, project_id, token, (error, privilegeLevel)->
@@ -390,7 +399,7 @@ module.exports = ProjectController =
 					showLinkSharingOnboarding: showLinkSharingOnboarding
 				timer.done()
 
-	_buildProjectList: (allProjects)->
+	_buildProjectList: (allProjects, v1Projects = [])->
 		{owned, readAndWrite, readOnly, tokenReadAndWrite, tokenReadOnly} = allProjects
 		projects = []
 		for project in owned
@@ -400,6 +409,8 @@ module.exports = ProjectController =
 			projects.push ProjectController._buildProjectViewModel(project, "readWrite", Sources.INVITE)
 		for project in readOnly
 			projects.push ProjectController._buildProjectViewModel(project, "readOnly", Sources.INVITE)
+		for project in v1Projects
+			projects.push ProjectController._buildV1ProjectViewModel(project)
 		# Token-access
 		#   Only add these projects if they're not already present, this gives us cascading access
 		#   from 'owner' => 'token-read-only'
@@ -424,9 +435,20 @@ module.exports = ProjectController =
 			archived: !!project.archived
 			owner_ref: project.owner_ref
 			tokens: project.tokens
+			isV1Project: false
 		}
 		return model
 
+	_buildV1ProjectViewModel: (project) ->
+		{
+			id: project.id
+			name: project.title
+			lastUpdated: new Date(project.updated_at * 1000) # Convert from epoch
+			accessLevel: "readOnly",
+			archived: project.removed || project.archived
+			isV1Project: true
+		}
+
 	_injectProjectOwners: (projects, callback = (error, projects) ->) ->
 		users = {}
 		for project in projects

+ 1 - 2
services/web/app/coffee/Features/User/UserController.coffee

@@ -51,7 +51,6 @@ module.exports = UserController =
 
 	updateUserSettings : (req, res)->
 		user_id = AuthenticationController.getLoggedInUserId(req)
-		usingExternalAuth = settings.ldap? or settings.saml?
 		logger.log user_id: user_id, "updating account settings"
 		User.findById user_id, (err, user)->
 			if err? or !user?
@@ -84,7 +83,7 @@ module.exports = UserController =
 				user.ace.syntaxValidation = req.body.syntaxValidation
 			user.save (err)->
 				newEmail = req.body.email?.trim().toLowerCase()
-				if !newEmail? or newEmail == user.email or usingExternalAuth
+				if !newEmail? or newEmail == user.email or req.externalAuthenticationSystemUsed()
 					# end here, don't update email
 					AuthenticationController.setInSessionUser(req, {first_name: user.first_name, last_name: user.last_name})
 					return res.sendStatus 200

+ 40 - 0
services/web/app/views/project/list/item.pug

@@ -0,0 +1,40 @@
+.col-xs-6
+	input.select-item(
+		select-individual,
+		type="checkbox",
+		ng-model="project.selected"
+		stop-propagation="click"
+		aria-label=translate('select_project') + " '{{ project.name }}'"
+	)
+	span
+		a.projectName(
+			ng-href="{{projectLink(project)}}"
+			stop-propagation="click"
+		) {{project.name}}
+		span(
+			ng-controller="TagListController"
+		)
+			.tag-label(
+				ng-repeat='tag in project.tags'
+				stop-propagation="click"
+			)
+				a.label.label-default.tag-label-name(
+					href,
+					ng-click="selectTag(tag)"
+				) {{tag.name}}
+				a.label.label-default.tag-label-remove(
+					href
+					ng-click="removeProjectFromTag(project, tag)"
+				) ×
+
+.col-xs-2
+	span.owner {{ownerName()}}
+	span(ng-if="isLinkSharingProject(project)")
+		|  
+		i.fa.fa-link.small(
+			tooltip=translate("link_sharing")
+			tooltip-placement="right"
+			tooltip-append-to-body="true"
+		)
+.col-xs-4
+	span.last-modified {{project.lastUpdated | formatDate}}

+ 13 - 41
services/web/app/views/project/list/project-list.pug

@@ -114,6 +114,10 @@
 					) #{translate("delete_forever")}
 
 .row.row-spaced
+	if noV1Connection
+		.col-xs-12
+			.alert.alert-warning No V1 Connection
+
 	.col-xs-12
 		.card.card-thin.project-list-card
 			ul.list-unstyled.project-list.structured-list(
@@ -142,47 +146,15 @@
 					ng-repeat="project in visibleProjects | orderBy:predicate:reverse",
 					ng-controller="ProjectListItemController"
 				)
-					.row(select-row)
-						.col-xs-6
-							input.select-item(
-								select-individual,
-								type="checkbox",
-								ng-model="project.selected"
-								stop-propagation="click"
-								aria-label=translate('select_project') + " '{{ project.name }}'"
-							)
-							span
-								a.projectName(
-									ng-href="{{projectLink(project)}}"
-									stop-propagation="click"
-								) {{project.name}}
-								span(
-									ng-controller="TagListController"
-								)
-									.tag-label(
-										ng-repeat='tag in project.tags'
-										stop-propagation="click"
-									)
-										a.label.label-default.tag-label-name(
-											href,
-											ng-click="selectTag(tag)"
-										) {{tag.name}} 
-										a.label.label-default.tag-label-remove(
-											href
-											ng-click="removeProjectFromTag(project, tag)"
-										) ×
-
-						.col-xs-2
-							span.owner {{ownerName()}}
-							span(ng-if="isLinkSharingProject(project)")
-								|  
-								i.fa.fa-link.small(
-									tooltip=translate("link_sharing")
-									tooltip-placement="right"
-									tooltip-append-to-body="true"
-								)
-						.col-xs-4
-							span.last-modified {{project.lastUpdated | formatDate}}
+					.row(
+						ng-if="!project.isV1Project"
+						select-row
+					)
+						include ./item
+					.row(
+						ng-if="project.isV1Project"
+					)
+						include ./v1-item
 				li(
 					ng-if="visibleProjects.length == 0",
 					ng-cloak

+ 8 - 0
services/web/app/views/project/list/side-bar.pug

@@ -45,6 +45,9 @@
 			a(href) #{translate("shared_with_you")}
 		li(ng-class="{active: (filter == 'archived')}", ng-click="filterProjects('archived')")
 			a(href) #{translate("deleted_projects")}
+		if isShowingV1Projects
+			li(ng-class="{active: (filter == 'v1')}", ng-click="filterProjects('v1')")
+				a(href) #{translate("v1_projects")}
 		li.separator
 			h2 #{translate("folders")}
 		li.tag(
@@ -62,6 +65,11 @@
 				)
 				span.name {{tag.name}} 
 					span.subdued  ({{tag.project_ids.length}})
+					span.v1-badge(
+						ng-if="tag.isV1",
+						ng-cloak,
+						aria-label=translate("v1_badge")
+					)
 			span.dropdown.tag-menu(dropdown)
 				a.dropdown-toggle(
 					href="#",

+ 11 - 0
services/web/app/views/project/list/v1-item.pug

@@ -0,0 +1,11 @@
+.col-xs-8
+	span.v1-badge(aria-label=translate("v1_badge"))
+	span
+		if settings.overleaf && settings.overleaf.host
+			a.projectName(
+					href=settings.overleaf.host + "/{{project.id}}"
+				stop-propagation="click"
+			) {{project.name}}
+
+.col-xs-4
+	span.last-modified {{project.lastUpdated | formatDate}}

+ 5 - 2
services/web/public/coffee/ide/editor/directives/aceEditor.coffee

@@ -35,7 +35,7 @@ define [
 			url = ace.config._moduleUrl(args...) + "?fingerprint=#{window.aceFingerprint}"
 			return url
 
-	App.directive "aceEditor", ($timeout, $compile, $rootScope, event_tracking, localStorage, $cacheFactory, labels, graphics, preamble, $http) ->
+	App.directive "aceEditor", ($timeout, $compile, $rootScope, event_tracking, localStorage, $cacheFactory, labels, graphics, preamble, $http, $q) ->
 		monkeyPatchSearch($rootScope, $compile)
 
 		return  {
@@ -97,7 +97,7 @@ define [
 
 				if scope.spellCheck # only enable spellcheck when explicitly required
 					spellCheckCache =  $cacheFactory("spellCheck-#{scope.name}", {capacity: 1000})
-					spellCheckManager = new SpellCheckManager(scope, editor, element, spellCheckCache, $http)
+					spellCheckManager = new SpellCheckManager(scope, editor, element, spellCheckCache, $http, $q)
 				undoManager           = new UndoManager(scope, editor, element)
 				highlightsManager     = new HighlightsManager(scope, editor, element)
 				cursorPositionManager = new CursorPositionManager(scope, editor, element, localStorage)
@@ -356,6 +356,7 @@ define [
 						session.setOption("useWorker", scope.syntaxValidation);
 
 					# now attach session to editor
+					editor.setReadOnly(true) # set to readonly until document change handlers are attached
 					editor.setSession(session)
 
 					doc = session.getDocument()
@@ -364,6 +365,8 @@ define [
 					editor.initing = true
 					sharejs_doc.attachToAce(editor)
 					editor.initing = false
+					# now ready to edit document
+					editor.setReadOnly(scope.readOnly) # respect the readOnly setting, normally false
 
 					resetScrollMargins()
 

+ 3 - 2
services/web/public/coffee/ide/editor/directives/aceEditor/auto-complete/AutoCompleteManager.coffee

@@ -149,7 +149,7 @@ define [
 			lastCharIsBackslash = lineUpToCursor.slice(-1) == "\\"
 			lastTwoChars = lineUpToCursor.slice(-2)
 			# Don't offer autocomplete on double-backslash, backslash-colon, etc
-			if lastTwoChars.match(/^\\[^a-z]$/)
+			if lastTwoChars.match(/^\\[^a-zA-Z]$/)
 				@editor?.completer?.detach?()
 				return
 			if commandName in ['begin', 'end']
@@ -229,8 +229,9 @@ define [
 											99999
 										)
 									)
+
 									if lineBeyondCursor
-										if partialCommandMatch = lineBeyondCursor.match(/^([a-z0-9]+)\{/)
+										if partialCommandMatch = lineBeyondCursor.match(/^([a-zA-Z0-9]+)\{/)
 											# We've got a partial command after the cursor
 											commandTail = partialCommandMatch[1]
 											# remove rest of the partial command, right of cursor

+ 2 - 2
services/web/public/coffee/ide/editor/directives/aceEditor/auto-complete/Helpers.coffee

@@ -17,8 +17,8 @@ define [
 			#    \includegraphics[width=\textwidth]{..
 			# should not match the \textwidth.
 			blankArguments = lineUpToCursor.replace /\[([^\]]*)\]/g, (args) ->
-				Array(args.length+1).join('.')
-			if m = blankArguments.match(/(\\[^\\]+)$/)
+				Array(args.length + 1).join('.')
+			if m = blankArguments.match(/(\\[^\\]*)$/)
 				return m.index
 			else
 				return -1

+ 12 - 5
services/web/public/coffee/ide/editor/directives/aceEditor/spell-check/SpellCheckManager.coffee

@@ -5,9 +5,9 @@ define [
 	Range = ace.require("ace/range").Range
 
 	class SpellCheckManager
-		constructor: (@$scope, @editor, @element, @cache, @$http) ->
+		constructor: (@$scope, @editor, @element, @cache, @$http, @$q) ->
 			$(document.body).append @element.find(".spell-check-menu")
-			
+			@inProgressRequest = null
 			@updatedLines = []
 			@highlightedWordManager = new HighlightedWordManager(@editor)
 
@@ -23,8 +23,8 @@ define [
 
 			@editor.on "changeSession", (e) =>
 				@highlightedWordManager.reset()
-				# if @inProgressRequest?
-				# 	@inProgressRequest.abort()
+				if @inProgressRequest?
+					@inProgressRequest.abort()
 
 				if @$scope.spellCheckEnabled and @$scope.spellCheckLanguage and @$scope.spellCheckLanguage != ""
 					@runSpellCheckSoon(200)
@@ -235,11 +235,18 @@ define [
 		apiRequest: (endpoint, data, callback = (error, result) ->)->
 			data.token = window.user.id
 			data._csrf = window.csrfToken
-			@$http.post("/spelling" + endpoint, data)
+			# use angular timeout option to cancel request if doc is changed
+			requestHandler = @$q.defer()
+			options = {timeout: requestHandler.promise}
+			httpRequest = @$http.post("/spelling" + endpoint, data, options)
 			.then (response) =>
 				callback(null, response.data)
 			.catch (response) =>
 				callback(new Error('api failure'))
+			# provide a method to cancel the request
+			abortRequest = () ->
+				requestHandler.resolve()
+			return { abort: abortRequest }
 
 		blacklistedCommandRegex: ///
 			\\                    # initial backslash

+ 5 - 1
services/web/public/coffee/ide/pdf/controllers/PdfController.coffee

@@ -85,7 +85,11 @@ define [
 			isTimeNonMonotonic = timeSinceLastCompile < 0
 
 			if isTimeNonMonotonic || timeSinceLastCompile >= AUTO_COMPILE_TIMEOUT
-				if (!ide.$scope.hasLintingError)
+				# If user has code check disabled, it is likely because they have
+				# linting errors that they are ignoring. Therefore it doesn't make sense
+				# to block auto compiles. It also causes problems where server-provided
+				# linting errors aren't cleared after typing
+				if (ide.$scope.settings.syntaxValidation and !ide.$scope.hasLintingError)
 					$scope.recompile(isAutoCompileOnChange: true)
 			else
 				# Extend remainder of timeout

+ 7 - 0
services/web/public/coffee/main/project-list/project-list.coffee

@@ -116,6 +116,10 @@ define [
 				if $scope.filter == "shared" and project.accessLevel == "owner"
 					visible = false
 
+				# Hide projects from V1 if we only want to see shared projects
+				if $scope.filter == "shared" and project.isV1Project
+					visible = false
+
 				# Hide projects we don't own if we only want to see owned projects
 				if $scope.filter == "owned" and project.accessLevel != "owner"
 					visible = false
@@ -129,6 +133,9 @@ define [
 					if project.archived
 						visible = false
 
+				if $scope.filter == "v1" and !project.isV1Project
+					visible = false
+
 				if visible
 					$scope.visibleProjects.push project
 				else

+ 1 - 0
services/web/public/stylesheets/_style_includes.less

@@ -78,6 +78,7 @@
 @import "app/invite.less";
 @import "app/review-features-page.less";
 @import "app/error-pages.less";
+@import "app/v1-badge.less";
 
 @import	"../js/libs/pdfListView/TextLayer.css";
 @import	"../js/libs/pdfListView/AnnotationsLayer.css";

+ 5 - 0
services/web/public/stylesheets/app/project-list.less

@@ -366,6 +366,11 @@ ul.project-list {
 				border-top-left-radius: 0;
 				border-bottom-left-radius: 0;
 			}
+
+		.v1-badge {
+			margin-right: 9px;
+			margin-left: 7px;
+		}
 	}
 	i.tablesort {
 		padding-left: 8px;

+ 10 - 0
services/web/public/stylesheets/app/v1-badge.less

@@ -0,0 +1,10 @@
+.v1-badge {
+	&:extend(.label);
+	&:extend(.label-default);
+	vertical-align: 11%;
+	padding: 1px 3px;
+	margin: 0 6px;
+	&:before {
+		content: "V1";
+	}
+}

+ 53 - 0
services/web/test/UnitTests/coffee/Project/ProjectControllerTests.coffee

@@ -66,6 +66,9 @@ describe "ProjectController", ->
 			protectTokens: sinon.stub()
 		@CollaboratorsHandler =
 			userIsTokenMember: sinon.stub().callsArgWith(2, null, false)
+		@Modules =
+			hooks:
+				fire: sinon.stub()
 		@ProjectController = SandboxedModule.require modulePath, requires:
 			"settings-sharelatex":@settings
 			"logger-sharelatex":
@@ -93,6 +96,7 @@ describe "ProjectController", ->
 			"../Analytics/AnalyticsManager": @AnalyticsManager
 			"../TokenAccess/TokenAccessHandler": @TokenAccessHandler
 			"../Collaborators/CollaboratorsHandler": @CollaboratorsHandler
+			"../../infrastructure/Modules": @Modules
 
 		@projectName = "£12321jkj9ujkljds"
 		@req =
@@ -263,6 +267,7 @@ describe "ProjectController", ->
 			@TagsHandler.getAllTags.callsArgWith(1, null, @tags, {})
 			@NotificationsHandler.getUserNotifications = sinon.stub().callsArgWith(1, null, @notifications, {})
 			@ProjectGetter.findAllUsersProjects.callsArgWith(2, null, @allProjects)
+			@Modules.hooks.fire.withArgs('findAllV1Projects', @user._id).yields(undefined) # Without integration module hook, cb returns undefined
 
 		it "should render the project/list page", (done)->
 			@res.render = (pageName, opts)=>
@@ -295,6 +300,53 @@ describe "ProjectController", ->
 				done()
 			@ProjectController.projectListPage @req, @res
 
+		describe 'with overleaf-integration-web-module hook', ->
+			beforeEach ->
+				@V1Response =
+					projects: [
+						{ id: '123mockV1Id', title: 'mock title', updated_at: 1509616411, removed: false, archived: false }
+						{ id: '456mockV1Id', title: 'mock title 2', updated_at: 1509616411, removed: true, archived: false }
+					],
+					tags: [
+						{ name: 'mock tag', project_ids: ['123mockV1Id'] }
+					]
+				@Modules.hooks.fire.withArgs('findAllV1Projects', @user._id).yields(null, [@V1Response]) # Need to wrap response in array, as multiple hooks could fire
+
+			it 'should include V1 projects', (done) ->
+				@res.render = (pageName, opts) =>
+					opts.projects.length.should.equal (
+						@projects.length +
+						@collabertions.length +
+						@readOnly.length +
+						@tokenReadAndWrite.length +
+						@tokenReadOnly.length +
+						@V1Response.projects.length
+					)
+					opts.projects.forEach (p) ->
+						# Check properties correctly mapped from V1
+						expect(p).to.have.property 'id'
+						expect(p).to.have.property 'name'
+						expect(p).to.have.property 'lastUpdated'
+						expect(p).to.have.property 'accessLevel'
+						expect(p).to.have.property 'archived'
+					done()
+				@ProjectController.projectListPage @req, @res
+
+			it 'should include V1 tags', (done) ->
+				@res.render = (pageName, opts) =>
+					opts.tags.length.should.equal (@tags.length + @V1Response.tags.length)
+					opts.tags.forEach (t) ->
+						expect(t).to.have.property 'name'
+						expect(t).to.have.property 'project_ids'
+					done()
+				@ProjectController.projectListPage @req, @res
+
+			it 'should have isShowingV1Projects flag', (done) ->
+				@res.render = (pageName, opts) =>
+					opts.isShowingV1Projects.should.equal true
+					done()
+				@ProjectController.projectListPage @req, @res
+
 	describe "projectListPage with duplicate projects", ->
 
 		beforeEach ->
@@ -338,6 +390,7 @@ describe "ProjectController", ->
 			@TagsHandler.getAllTags.callsArgWith(1, null, @tags, {})
 			@NotificationsHandler.getUserNotifications = sinon.stub().callsArgWith(1, null, @notifications, {})
 			@ProjectGetter.findAllUsersProjects.callsArgWith(2, null, @allProjects)
+			@Modules.hooks.fire.withArgs('findAllV1Projects', @user._id).yields(undefined) # Without integration module hook, cb returns undefined
 
 		it "should render the project/list page", (done)->
 			@res.render = (pageName, opts)=>

+ 2 - 4
services/web/test/UnitTests/coffee/User/UserControllerTests.coffee

@@ -187,6 +187,7 @@ describe "UserController", ->
 	describe "updateUserSettings", ->
 		beforeEach ->
 			@newEmail = "hello@world.com"
+			@req.externalAuthenticationSystemUsed = sinon.stub().returns(false)
 
 		it "should call save", (done)->
 			@req.body = {}
@@ -280,10 +281,7 @@ describe "UserController", ->
 			beforeEach ->
 				@UserUpdater.changeEmailAddress.callsArgWith(2)
 				@newEmail = 'someone23@example.com'
-				@settings.ldap = {active: true}
-
-			afterEach ->
-				delete @settings.ldap
+				@req.externalAuthenticationSystemUsed = sinon.stub().returns(true)
 
 			it 'should not set a new email', (done) ->
 				@req.body.email = @newEmail

+ 5 - 9
services/web/test/smoke/coffee/SmokeTests.coffee

@@ -33,23 +33,19 @@ describe "Opening", ->
 				return done(err)
 			logger.log "smoke test: clearing rate limit "
 			require("../../../app/js/infrastructure/RateLimiter.js").clearRateLimit "open-project", "#{Settings.smokeTest.projectId}:#{Settings.smokeTest.userId}", ->
-				logger.log "smoke test: hitting /register"
+				logger.log "smoke test: hitting dev/csrf"
 				command =  """
-					curl -H  "X-Forwarded-Proto: https" -c #{cookeFilePath} #{buildUrl('register')}
+					curl -H  "X-Forwarded-Proto: https" -c #{cookeFilePath} #{buildUrl('dev/csrf')}
 				"""
 				child.exec command, (err, stdout, stderr)->
 					if err? then done(err)
-					csrfMatches = stdout.match("<input name=\"_csrf\" type=\"hidden\" value=\"(.*?)\">")
-					if !csrfMatches?
-						logger.err stdout:stdout, "smoke test: does not have csrf token"
-						return done("smoke test: does not have csrf token")
-					csrf = csrfMatches[1]
+					csrf = stdout
 					logger.log "smoke test: converting cookie file 1"
 					convertCookieFile (err) ->
 						return done(err) if err?
-						logger.log "smoke test: hitting /register with csrf"
+						logger.log "smoke test: hitting /login with csrf"
 						command = """
-							curl -c #{cookeFilePath} -H "Content-Type: application/json" -H "X-Forwarded-Proto: https" -d '{"_csrf":"#{csrf}", "email":"#{Settings.smokeTest.user}", "password":"#{Settings.smokeTest.password}"}' #{buildUrl('register')}
+							curl -c #{cookeFilePath} -H "Content-Type: application/json" -H "X-Forwarded-Proto: https" -d '{"_csrf":"#{csrf}", "email":"#{Settings.smokeTest.user}", "password":"#{Settings.smokeTest.password}"}' #{buildUrl('login')}
 						"""
 						child.exec command, (err) ->
 							return done(err) if err?