@@ -96,39 +96,52 @@ passport.use(new GitHubStrategy({
9696} , ( req , accessToken , refreshToken , profile , done ) => {
9797 User . findOne ( { github : profile . id } , ( findByGithubErr , existingUser ) => {
9898 if ( existingUser ) {
99+ if ( req . user && req . user . email !== existingUser . email ) {
100+ done ( new Error ( 'GitHub account is already linked to another account.' ) ) ;
101+ return ;
102+ }
99103 done ( null , existingUser ) ;
100104 return ;
101105 }
102106
103107 const emails = getVerifiedEmails ( profile . emails ) ;
104108 const primaryEmail = getPrimaryEmail ( profile . emails ) ;
105109
106- User . findByEmail ( emails , ( findByEmailErr , existingEmailUser ) => {
107- if ( existingEmailUser ) {
108- existingEmailUser . email = existingEmailUser . email || primaryEmail ;
109- existingEmailUser . github = profile . id ;
110- existingEmailUser . username = existingEmailUser . username || profile . username ;
111- existingEmailUser . tokens . push ( { kind : 'github' , accessToken } ) ;
112- existingEmailUser . name = existingEmailUser . name || profile . displayName ;
113- existingEmailUser . verified = User . EmailConfirmation . Verified ;
114- existingEmailUser . save ( saveErr => done ( null , existingEmailUser ) ) ;
115- } else {
116- let { username } = profile ;
117- User . findByUsername ( username , { caseInsensitive : true } , ( findByUsernameErr , existingUsernameUser ) => {
118- if ( existingUsernameUser ) {
119- username = generateUniqueUsername ( username ) ;
120- }
121- const user = new User ( ) ;
122- user . email = primaryEmail ;
123- user . github = profile . id ;
124- user . username = profile . username ;
125- user . tokens . push ( { kind : 'github' , accessToken } ) ;
126- user . name = profile . displayName ;
127- user . verified = User . EmailConfirmation . Verified ;
128- user . save ( saveErr => done ( null , user ) ) ;
129- } ) ;
110+ if ( req . user ) {
111+ if ( ! req . user . github ) {
112+ req . user . github = profile . id ;
113+ req . user . tokens . push ( { kind : 'github' , accessToken } ) ;
114+ req . user . verified = User . EmailConfirmation . Verified ;
130115 }
131- } ) ;
116+ req . user . save ( saveErr => done ( null , req . user ) ) ;
117+ } else {
118+ User . findByEmail ( emails , ( findByEmailErr , existingEmailUser ) => {
119+ if ( existingEmailUser ) {
120+ existingEmailUser . email = existingEmailUser . email || primaryEmail ;
121+ existingEmailUser . github = profile . id ;
122+ existingEmailUser . username = existingEmailUser . username || profile . username ;
123+ existingEmailUser . tokens . push ( { kind : 'github' , accessToken } ) ;
124+ existingEmailUser . name = existingEmailUser . name || profile . displayName ;
125+ existingEmailUser . verified = User . EmailConfirmation . Verified ;
126+ existingEmailUser . save ( saveErr => done ( null , existingEmailUser ) ) ;
127+ } else {
128+ let { username } = profile ;
129+ User . findByUsername ( username , { caseInsensitive : true } , ( findByUsernameErr , existingUsernameUser ) => {
130+ if ( existingUsernameUser ) {
131+ username = generateUniqueUsername ( username ) ;
132+ }
133+ const user = new User ( ) ;
134+ user . email = primaryEmail ;
135+ user . github = profile . id ;
136+ user . username = profile . username ;
137+ user . tokens . push ( { kind : 'github' , accessToken } ) ;
138+ user . name = profile . displayName ;
139+ user . verified = User . EmailConfirmation . Verified ;
140+ user . save ( saveErr => done ( null , user ) ) ;
141+ } ) ;
142+ }
143+ } ) ;
144+ }
132145 } ) ;
133146} ) ) ;
134147
@@ -144,49 +157,62 @@ passport.use(new GoogleStrategy({
144157} , ( req , accessToken , refreshToken , profile , done ) => {
145158 User . findOne ( { google : profile . _json . emails [ 0 ] . value } , ( findByGoogleErr , existingUser ) => {
146159 if ( existingUser ) {
160+ if ( req . user && req . user . email !== existingUser . email ) {
161+ done ( new Error ( 'Google account is already linked to another account.' ) ) ;
162+ return ;
163+ }
147164 done ( null , existingUser ) ;
148165 return ;
149166 }
150167
151168 const primaryEmail = profile . _json . emails [ 0 ] . value ;
152169
153- User . findByEmail ( primaryEmail , ( findByEmailErr , existingEmailUser ) => {
154- let username = profile . _json . emails [ 0 ] . value . split ( '@' ) [ 0 ] ;
155- User . findByUsername ( username , { caseInsensitive : true } , ( findByUsernameErr , existingUsernameUser ) => {
156- if ( existingUsernameUser ) {
157- username = generateUniqueUsername ( username ) ;
158- }
159- // what if a username is already taken from the display name too?
160- // then, append a random friendly word?
161- if ( existingEmailUser ) {
162- existingEmailUser . email = existingEmailUser . email || primaryEmail ;
163- existingEmailUser . google = profile . _json . emails [ 0 ] . value ;
164- existingEmailUser . username = existingEmailUser . username || username ;
165- existingEmailUser . tokens . push ( { kind : 'google' , accessToken } ) ;
166- existingEmailUser . name = existingEmailUser . name || profile . _json . displayName ;
167- existingEmailUser . verified = User . EmailConfirmation . Verified ;
168- existingEmailUser . save ( ( saveErr ) => {
169- if ( saveErr ) {
170- console . log ( saveErr ) ;
171- }
172- done ( null , existingEmailUser ) ;
173- } ) ;
174- } else {
175- const user = new User ( ) ;
176- user . email = primaryEmail ;
177- user . google = profile . _json . emails [ 0 ] . value ;
178- user . username = username ;
179- user . tokens . push ( { kind : 'google' , accessToken } ) ;
180- user . name = profile . _json . displayName ;
181- user . verified = User . EmailConfirmation . Verified ;
182- user . save ( ( saveErr ) => {
183- if ( saveErr ) {
184- console . log ( saveErr ) ;
185- }
186- done ( null , user ) ;
187- } ) ;
188- }
170+ if ( req . user ) {
171+ if ( ! req . user . google ) {
172+ req . user . google = profile . _json . emails [ 0 ] . value ;
173+ req . user . tokens . push ( { kind : 'google' , accessToken } ) ;
174+ req . user . verified = User . EmailConfirmation . Verified ;
175+ }
176+ req . user . save ( saveErr => done ( null , req . user ) ) ;
177+ } else {
178+ User . findByEmail ( primaryEmail , ( findByEmailErr , existingEmailUser ) => {
179+ let username = profile . _json . emails [ 0 ] . value . split ( '@' ) [ 0 ] ;
180+ User . findByUsername ( username , { caseInsensitive : true } , ( findByUsernameErr , existingUsernameUser ) => {
181+ if ( existingUsernameUser ) {
182+ username = generateUniqueUsername ( username ) ;
183+ }
184+ // what if a username is already taken from the display name too?
185+ // then, append a random friendly word?
186+ if ( existingEmailUser ) {
187+ existingEmailUser . email = existingEmailUser . email || primaryEmail ;
188+ existingEmailUser . google = profile . _json . emails [ 0 ] . value ;
189+ existingEmailUser . username = existingEmailUser . username || username ;
190+ existingEmailUser . tokens . push ( { kind : 'google' , accessToken } ) ;
191+ existingEmailUser . name = existingEmailUser . name || profile . _json . displayName ;
192+ existingEmailUser . verified = User . EmailConfirmation . Verified ;
193+ existingEmailUser . save ( ( saveErr ) => {
194+ if ( saveErr ) {
195+ console . log ( saveErr ) ;
196+ }
197+ done ( null , existingEmailUser ) ;
198+ } ) ;
199+ } else {
200+ const user = new User ( ) ;
201+ user . email = primaryEmail ;
202+ user . google = profile . _json . emails [ 0 ] . value ;
203+ user . username = username ;
204+ user . tokens . push ( { kind : 'google' , accessToken } ) ;
205+ user . name = profile . _json . displayName ;
206+ user . verified = User . EmailConfirmation . Verified ;
207+ user . save ( ( saveErr ) => {
208+ if ( saveErr ) {
209+ console . log ( saveErr ) ;
210+ }
211+ done ( null , user ) ;
212+ } ) ;
213+ }
214+ } ) ;
189215 } ) ;
190- } ) ;
216+ }
191217 } ) ;
192218} ) ) ;
0 commit comments