Skip to content
GitLab
Explore
Projects
Groups
Topics
Snippets
Projects
Groups
Topics
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Register
Sign in
Toggle navigation
Menu
UPSMF
uphrh-sb-devops
Commits
b4ad1174
Commit
b4ad1174
authored
5 years ago
by
Devesh
Browse files
Options
Download
Patches
Plain Diff
Issue #SB-13773 fix:secure auto merge related changes for keycloack
parent
1ab5ada8
master
login-changes
loginRegisterBtn
prasath-release-5.1.0
release-5.1.0
release-5.1.0-api
release-5.1.0-apiuat
release-5.1.0-bulk-enrol-unenrol
release-5.1.0-uat
release-5.1.0-uatLatest
release-5.1.0-uatapi
release-5.1.0-upsmf-prod
release-uat-nginx
revert-5-login-changes
upstream/release-5.1.0-vdn
3nodeinstall
3node-prior-rebase-2-5
3node-2.6.0
3node
3node_bak_new
temp-ratelimit_RC1
tag-for-backups
tag-for-backups_RC1
tag-2.4.0
service-rename-player-2.5.0_RC9
service-rename-kong-2.5.0_RC4
revert-incorrect
revert-942-release-2.6.0
revert-872-SC-1392-ftl-fix
release-dock-0.0.3_RC2
release-dock-0.0.3_RC1
release-5.2.0-inquiry_RC1
release-5.1.0_RC3
release-5.1.0_RC2
release-5.1.0_RC1
release-5.0.2
release-5.0.2_RC1
release-5.0.1
release-5.0.1_RC1
release-5.0.0
release-5.0.0_RC5
release-5.0.0_RC4
release-5.0.0_RC3
release-5.0.0_RC2
release-5.0.0_RC1
release-5.0.0-vdn_RC1
release-4.10.2_RC1
release-4.10.1
release-4.10.1_RC2
release-4.10.1_RC1
release-4.10.0
release-4.10.0_RC1
release-4.10.0-vdn_RC1
release-4.9.0
release-4.9.0_RC4
release-4.9.0_RC3
release-4.9.0_RC2
release-4.9.0_RC1
release-4.9.0-vdn_RC2
release-4.9.0-vdn_RC1
release-4.8.0
release-4.8.0_RC8
release-4.8.0_RC7
release-4.8.0_RC6
release-4.8.0_RC5
release-4.8.0_RC4
release-4.8.0_RC3
release-4.8.0_RC2
release-4.8.0_RC1
release-4.8.0-vdn_RC1
release-4.7.0
release-4.7.0_RC3
release-4.7.0_RC2
release-4.7.0_RC1
release-4.7.0-vdn_RC1
release-4.6.0
release-4.6.0_RC4
release-4.6.0_RC3
release-4.6.0_RC2
release-4.6.0_RC1
release-4.5.0
release-4.5.0_RC6
release-4.5.0_RC5
release-4.5.0_RC4
release-4.5.0_RC3
release-4.5.0_RC2
release-4.5.0_RC1
release-4.4.1_RC2
release-4.4.1_RC1
release-4.4.1-vdn_RC2
release-4.4.1-vdn_RC1
release-4.4.0
release-4.4.0_RC10
release-4.4.0_RC9
release-4.4.0_RC8
release-4.4.0_RC7
release-4.4.0_RC6
release-4.4.0_RC5
release-4.4.0_RC4
release-4.4.0_RC3
release-4.4.0_RC2
release-4.4.0_RC1
release-4.3.0
release-4.3.0_RC7
release-4.3.0_RC6
release-4.3.0_RC5
release-4.3.0_RC4
release-4.3.0_RC3
release-4.3.0_RC2
release-4.3.0_RC1
release-4.2.0
release-4.2.0_RC6
release-4.2.0_RC5
release-4.2.0_RC4
release-4.2.0_RC3
release-4.2.0_RC2
release-4.2.0_RC1
release-4.1.0
release-4.1.0_RC20
release-4.1.0_RC19
release-4.1.0_RC18
release-4.1.0_RC17
release-4.1.0_RC16
release-4.1.0_RC15
release-4.1.0_RC14
release-4.1.0_RC13
release-4.1.0_RC12
release-4.1.0_RC11
release-4.1.0_RC10
release-4.1.0_RC9
release-4.1.0_RC8
release-4.1.0_RC7
release-4.1.0_RC6
release-4.1.0_RC5
release-4.1.0_RC4
release-4.1.0_RC3
release-4.1.0_RC2
release-4.1.0_RC1
release-4.0.0
release-4.0.0_RC6
release-4.0.0_RC5
release-4.0.0_RC4
release-4.0.0_RC3
release-4.0.0_RC2
release-4.0.0_RC1
release-3.9.0
release-3.9.0_RC18
release-3.9.0_RC17
release-3.9.0_RC16
release-3.9.0_RC15
release-3.9.0_RC14
release-3.9.0_RC13
release-3.9.0_RC12
release-3.9.0_RC11
release-3.9.0_RC10
release-3.9.0_RC9
release-3.9.0_RC8
release-3.9.0_RC7
release-3.9.0_RC6
release-3.9.0_RC5
release-3.9.0_RC4
release-3.9.0_RC3
release-3.9.0_RC2
release-3.9.0_RC1
release-3.8.0
release-3.8.0_RC14
release-3.8.0_RC13
release-3.8.0_RC12
release-3.8.0_RC11
release-3.8.0_RC10
release-3.8.0_RC9
release-3.8.0_RC8
release-3.8.0_RC7
release-3.8.0_RC6
release-3.8.0_RC5
release-3.8.0_RC4
release-3.8.0_RC3
release-3.8.0_RC2
release-3.8.0_RC1
release-3.7.0_RC16
release-3.7.0_RC15
release-3.7.0_RC14
release-3.7.0_RC13
release-3.7.0_RC12
release-3.7.0_RC11
release-3.7.0_RC10
release-3.7.0_RC9
release-3.7.0_RC8
release-3.7.0_RC7
release-3.7.0_RC6
release-3.7.0_RC5
release-3.7.0_RC4
release-3.7.0_RC3
release-3.7.0_RC2
release-3.7.0_RC1
release-3.6.5_RC1
release-3.6.0_RC8
release-3.6.0_RC7
release-3.6.0_RC6
release-3.6.0_RC5
release-3.6.0_RC4
release-3.6.0_RC3
release-3.6.0_RC2
release-3.6.0_RC1
release-3.5.0
release-3.5.0_RC8
release-3.5.0_RC7
release-3.5.0_RC6
release-3.5.0_RC5
release-3.5.0_RC4
release-3.5.0_RC3
release-3.5.0_RC2
release-3.5.0_RC1
release-3.4.0
release-3.4.0_RC21
release-3.4.0_RC20
release-3.4.0_RC19
release-3.4.0_RC18
release-3.4.0_RC17
release-3.4.0_RC16
release-3.4.0_RC15
release-3.4.0_RC14
release-3.4.0_RC13
release-3.4.0_RC12
release-3.4.0_RC11
release-3.4.0_RC10
release-3.4.0_RC9
release-3.4.0_RC8
release-3.4.0_RC7
release-3.4.0_RC6
release-3.4.0_RC5
release-3.4.0_RC4
release-3.4.0_RC3
release-3.4.0_RC2
release-3.4.0_RC1
release-3.3.0_RC24
release-3.3.0_RC23
release-3.3.0_RC22
release-3.3.0_RC21
release-3.3.0_RC20
release-3.3.0_RC19
release-3.3.0_RC18
release-3.3.0_RC17
release-3.3.0_RC16
release-3.3.0_RC15
release-3.3.0_RC14
release-3.3.0_RC13
release-3.3.0_RC12
release-3.3.0_RC11
release-3.3.0_RC10
release-3.3.0_RC9
release-3.3.0_RC8
release-3.3.0_RC7
release-3.3.0_RC6
release-3.3.0_RC5
release-3.3.0_RC4
release-3.3.0_RC3
release-3.3.0_RC2
release-3.3.0_RC1
release-3.2.7
release-3.2.7_RC14
release-3.2.7_RC13
release-3.2.7_RC12
release-3.2.7_RC11
release-3.2.7_RC10
release-3.2.7_RC9
release-3.2.7_RC8
release-3.2.7_RC7
release-3.2.7_RC6
release-3.2.7_RC5
release-3.2.7_RC4
release-3.2.7_RC3
release-3.2.7_RC2
release-3.2.7_RC1
release-3.2.0_RC21
release-3.2.0_RC20
release-3.2.0_RC19
release-3.2.0_RC18
release-3.2.0_RC17
release-3.2.0_RC16
release-3.2.0_RC15
release-3.2.0_RC14
release-3.2.0_RC13
release-3.2.0_RC12
release-3.2.0_RC11
release-3.2.0_RC10
release-3.2.0_RC9
release-3.2.0_RC8
release-3.2.0_RC7
release-3.2.0_RC6
release-3.2.0_RC5
release-3.2.0_RC4
release-3.2.0_RC3
release-3.2.0_RC2
release-3.2.0_RC1
release-3.1.0
release-3.1.0_RC10
release-3.1.0_RC9
release-3.1.0_RC8
release-3.1.0_RC7
release-3.1.0_RC6
release-3.1.0_RC5
release-3.1.0_RC4
release-3.1.0_RC3
release-3.1.0_RC2
release-3.1.0_RC1
release-3.0.1_RC7
release-3.0.1_RC6
release-3.0.1_RC5
release-3.0.1_RC4
release-3.0.1_RC3
release-3.0.1_RC2
release-3.0.1_RC1
release-3.0.0
release-3.0.0_RC42
release-3.0.0_RC41
release-3.0.0_RC40
release-3.0.0_RC39
release-3.0.0_RC38
release-3.0.0_RC37
release-3.0.0_RC36
release-3.0.0_RC35
release-3.0.0_RC34
release-3.0.0_RC33
release-3.0.0_RC32
release-3.0.0_RC31
release-3.0.0_RC30
release-3.0.0_RC29
release-3.0.0_RC28
release-3.0.0_RC27
release-3.0.0_RC26
release-3.0.0_RC25
release-3.0.0_RC24
release-3.0.0_RC23
release-3.0.0_RC22
release-3.0.0_RC21
release-3.0.0_RC20
release-3.0.0_RC19
release-3.0.0_RC18
release-3.0.0_RC17
release-3.0.0_RC16
release-3.0.0_RC15
release-3.0.0_RC14
release-3.0.0_RC13
release-3.0.0_RC12
release-3.0.0_RC11
release-3.0.0_RC10
release-3.0.0_RC9
release-3.0.0_RC8
release-3.0.0_RC7
release-3.0.0_RC6
release-3.0.0_RC5
release-3.0.0_RC4
release-3.0.0_RC3
release-3.0.0_RC2
release-3.0.0_RC1
release-2.10.0
release-2.10.0_RC24
release-2.10.0_RC23
release-2.10.0_RC22
release-2.10.0_RC21
release-2.10.0_RC20
release-2.10.0_RC19
release-2.10.0_RC18
release-2.10.0_RC17
release-2.10.0_RC16
release-2.10.0_RC15
release-2.10.0_RC14
release-2.10.0_RC13
release-2.10.0_RC12
release-2.10.0_RC11
release-2.10.0_RC10
release-2.10.0_RC9
release-2.10.0_RC8
release-2.10.0_RC7
release-2.10.0_RC6
release-2.10.0_RC5
release-2.10.0_RC4
release-2.10.0_RC3
release-2.10.0_RC2
release-2.10.0_RC1
release-2.9.0_RC13
release-2.9.0_RC12
release-2.9.0_RC11
release-2.9.0_RC10
release-2.9.0_RC9
release-2.9.0_RC8
release-2.9.0_RC7
release-2.9.0_RC6
release-2.9.0_RC5
release-2.9.0_RC4
release-2.9.0_RC3
release-2.9.0_RC2
release-2.9.0_RC1
release-2.8.0
release-2.8.0_RC34
release-2.8.0_RC33
release-2.8.0_RC32
release-2.8.0_RC31
release-2.8.0_RC30
release-2.8.0_RC29
release-2.8.0_RC28
release-2.8.0_RC27
release-2.8.0_RC26
release-2.8.0_RC25
release-2.8.0_RC24
release-2.8.0_RC23
release-2.8.0_RC22
release-2.8.0_RC21
release-2.8.0_RC20
release-2.8.0_RC19
release-2.8.0_RC18
release-2.8.0_RC17
release-2.8.0_RC16
release-2.8.0_RC15
release-2.8.0_RC14
release-2.8.0_RC13
release-2.8.0_RC12
release-2.8.0_RC11
release-2.8.0_RC10
release-2.8.0_RC9
release-2.8.0_RC8
release-2.8.0_RC7
release-2.8.0_RC6
release-2.8.0_RC5
release-2.8.0_RC4
release-2.8.0_RC3
release-2.8.0_RC2
release-2.8.0_RC1
release-2.8.0-desktopapis-hotfix
release-2.7.0
release-2.7.0_RC16
release-2.7.0_RC15
release-2.7.0_RC14
release-2.7.0_RC13
release-2.7.0_RC12
release-2.7.0_RC11
release-2.7.0_RC10
release-2.7.0_RC9
release-2.7.0_RC8
release-2.7.0_RC7
release-2.7.0_RC6
release-2.7.0_RC5
release-2.7.0_RC4
release-2.7.0_RC3
release-2.7.0_RC2
release-2.7.0_RC1
release-2.6.5_RC3
release-2.6.5_RC2
release-2.6.5_RC1
release-2.6.5_Kong10_RC2
release-2.6.0
release-2.6.0_kong9
release-2.6.0_kong_RC1
release-2.6.0_RC25
release-2.6.0_RC24
release-2.6.0_RC23
release-2.6.0_RC22
release-2.6.0_RC21
release-2.6.0_RC20
release-2.6.0_RC19
release-2.6.0_RC18
release-2.6.0_RC17
release-2.6.0_RC16
release-2.6.0_RC15
release-2.6.0_RC14
release-2.6.0_RC13
release-2.6.0_RC12
release-2.6.0_RC11
release-2.6.0_RC10
release-2.6.0_RC9
release-2.6.0_RC8
release-2.6.0_RC7
release-2.6.0_RC6
release-2.6.0_RC5
release-2.6.0_RC4
release-2.6.0_RC3
release-2.6.0_RC2
release-2.6.0_RC1
release-2.6.0-k8s_9467d13
release-2.5.0
release-2.5.0_RC12
release-2.5.0_RC11
release-2.5.0_RC10
release-2.5.0_RC9
release-2.5.0_RC9_portalfix
release-2.5.0_RC8
release-2.5.0_RC7
release-2.5.0_RC6
release-2.5.0_RC5
release-2.5.0_RC4
release-2.5.0_RC4_kong
release-2.5.0_RC3
release-2.5.0_RC2
release-2.5.0_RC1
release-2.4.0
release-2.4.0_RC9
release-2.4.0_RC9_portal_RC2
release-2.4.0_RC9_portal_RC1
release-2.4.0_RC8
release-2.4.0_RC7
release-2.4.0_RC6
release-2.4.0_RC5
release-2.4.0_RC4
portal-fix
player-var
original-tag-2.4.0
master_e26ae85
loadtest-release-2.10.0_nginx_prometheus
kubernetes
keycloak-3.2.0
keycloak-3.2.0_RC1
keycloak7_RC1
jenkins-config
fix-tag-2.4.0
es-mapping
dock-0.0.3_RC7
dock-0.0.3_RC6
dock-0.0.3_RC5
dock-0.0.3_RC4
dock-0.0.3_RC3
dock-0.0.3_RC2
dock-0.0.3_RC1
dock-0.0.3-before-delete
dock-0.0.2_RC13
dock-0.0.2_RC12
dock-0.0.2_RC11
dock-0.0.2_RC10
dock-0.0.2_RC9
dock-0.0.2_RC8
dock-0.0.2_RC7
dock-0.0.2_RC6
dock-0.0.2_RC5
dock-0.0.2_RC4
dock-0.0.2_RC3
dock-0.0.2_RC2
dock-0.0.2_RC1
SMYALTAMASH-patch-1
No related merge requests found
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
ansible/artifacts/sunbird/login/login.ftl
+2
-0
ansible/artifacts/sunbird/login/login.ftl
ansible/artifacts/sunbird/login/messages/messages_en.properties
+2
-0
...e/artifacts/sunbird/login/messages/messages_en.properties
ansible/artifacts/sunbird/login/resources/js/login.js
+93
-2
ansible/artifacts/sunbird/login/resources/js/login.js
with
97 additions
and
2 deletions
+97
-2
ansible/artifacts/sunbird/login/login.ftl
+
2
−
0
View file @
b4ad1174
...
...
@@ -14,6 +14,7 @@
<div id="signIn" class="signInHead mt-27">$
{
msg
(
"doSignIn"
)}
</div>
</div>
<p id="mergeAccountMessage" class="hide mb-0 textCenter">$
{
msg
(
"mergeAccountMessage"
)}
</p>
<p id="migrateAccountMessage" class="hide mb-0 textCenter">$
{
msg
(
"migrateAccountMessage"
)}
</p>
<div class="formMsg mb-28 textCenter">
<#if message?has_content>
<div id="error-summary" class="ui text $
{
message
.type
}
">
...
...
@@ -57,6 +58,7 @@
</label>
</div>
<input class=" mt-8" id="password" onfocusin="inputBoxFocusIn(this)" onfocusout="inputBoxFocusOut(this)" name="password" type="password" autocomplete="off" />
<span class="ui text error hide" id="inCorrectPasswordError">$
{
msg
(
"inCorrectPasswordError"
)}
</span>
</div>
<div class="field">
<button id="login" class="mt-36 ui fluid button">$
{
msg
(
"doSignIn"
)}
</button>
...
...
This diff is collapsed.
Click to expand it.
ansible/artifacts/sunbird/login/messages/messages_en.properties
+
2
−
0
View file @
b4ad1174
...
...
@@ -54,6 +54,8 @@ noAccount=Don''t have an account?
username
=
Username or Mobile number
goBack
=
<<Go Back
mergeAccountMessage
=
Enter Mobile number / Email ID OR use Google Sign in to identify the account from which you want to merge usage details
migrateAccountMessage
=
Confirm the password for the DIKSHA account you want to merge of cick Sign in with Google to sign in using your Gmail account
inCorrectPasswordError
=
The password entered is incorrect. Enter the password again.
emailOrPhone
=
Mobile number / Email ID
placeholderForEmailOrPhone
=
Enter Mobile number / Email ID
firstName
=
First name
...
...
This diff is collapsed.
Click to expand it.
ansible/artifacts/sunbird/login/resources/js/login.js
+
93
−
2
View file @
b4ad1174
...
...
@@ -49,6 +49,7 @@ window.onload = function(){
hideElement
(
"
kc-registration
"
);
hideElement
(
"
stateButton
"
);
hideElement
(
"
fgtKeycloakFlow
"
);
hideElement
(
"
fgtPortalFlow
"
);
// change sign in label with merge label
var
signIn
=
document
.
getElementById
(
"
signIn
"
);
if
(
signIn
)
{
...
...
@@ -74,7 +75,89 @@ window.onload = function(){
mergeAccountMessage
.
className
=
mergeAccountMessage
.
className
.
replace
(
"
hide
"
,
""
);
}
}
}
var
response_type
=
(
new
URLSearchParams
(
window
.
location
.
search
)).
get
(
'
response_type
'
);
if
((
new
URLSearchParams
(
window
.
location
.
search
)).
get
(
'
automerge
'
)
!==
'
1
'
&&
response_type
===
'
code
'
)
{
localStorage
.
clear
();
}
var
autoMerge
=
getValue
(
'
automerge
'
);
if
(
autoMerge
===
'
1
'
)
{
decoratePage
(
'
autoMerge
'
);
storeValueForMigration
();
}
};
var
storeValueForMigration
=
function
()
{
// storing values in localstorage for future references
localStorage
.
setItem
(
'
automerge
'
,
getValue
(
'
automerge
'
));
localStorage
.
setItem
(
'
goBackUrl
'
,
getValue
(
'
goBackUrl
'
));
localStorage
.
setItem
(
'
identifierValue
'
,
getValue
(
'
identifierValue
'
));
};
var
getValue
=
function
(
valueId
)
{
var
value
=
(
new
URLSearchParams
(
window
.
location
.
search
)).
get
(
valueId
);
if
(
value
)
{
localStorage
.
setItem
(
'
renderingType
'
,
'
queryParams
'
);
return
value
}
else
{
value
=
localStorage
.
getItem
(
valueId
);
if
(
value
)
{
localStorage
.
setItem
(
'
renderingType
'
,
'
localStorage
'
);
}
return
value
}
};
var
decoratePage
=
function
(
pageType
)
{
if
(
pageType
===
'
autoMerge
'
)
{
var
identifierValue
=
getValue
(
'
identifierValue
'
);
var
goBackUrl
=
getValue
(
'
goBackUrl
'
);
var
signIn
=
document
.
getElementById
(
"
signIn
"
);
if
(
signIn
)
{
signIn
.
innerText
=
'
Merge Account
'
;
signIn
.
classList
.
add
(
'
fs-22
'
);
}
setElementValue
(
'
username
'
,
identifierValue
);
var
elementsToHide
=
[
'
kc-registration
'
,
'
stateButton
'
,
'
fgtKeycloakFlow
'
,
'
fgtPortalFlow
'
,
'
usernameLabel
'
,
'
usernameLabelPlaceholder
'
,
'
username
'
];
unHideElement
(
'
migrateAccountMessage
'
);
unHideElement
(
'
goBack
'
);
var
goBackElement
=
document
.
getElementById
(
"
goBack
"
);
if
(
goBackElement
)
{
goBackElement
.
href
=
goBackUrl
;
}
if
(
localStorage
.
getItem
(
'
renderingType
'
)
===
'
localStorage
'
)
{
unHideElement
(
'
selfSingUp
'
);
var
errorElement
=
document
.
getElementById
(
'
error-summary
'
);
if
(
errorElement
)
{
if
(
errorElement
.
innerText
===
'
Invalid email ID/Mobile number or password. Please try again with valid credentials
'
)
{
unHideElement
(
'
inCorrectPasswordError
'
);
}
elementsToHide
.
push
(
'
error-summary
'
);
//hideElement('error-summary');
}
}
for
(
var
i
=
0
;
i
<
elementsToHide
.
length
;
i
++
)
{
hideElement
(
elementsToHide
[
i
]);
}
}
};
var
unHideElement
=
function
(
elementId
)
{
var
elementToUnHide
=
document
.
getElementById
(
elementId
);
if
(
elementToUnHide
)
{
elementToUnHide
.
className
=
elementToUnHide
.
className
.
replace
(
"
hide
"
,
""
);
}
};
var
setElementValue
=
function
(
elementId
,
elementValue
)
{
var
element
=
document
.
getElementById
(
elementId
);
if
(
element
)
{
element
.
value
=
elementValue
;
}
};
var
storeLocation
=
function
(){
sessionStorage
.
setItem
(
'
url
'
,
window
.
location
.
href
);
}
...
...
@@ -102,6 +185,10 @@ var makeDivUnclickable = function() {
};
var
inputBoxFocusIn
=
function
(
currentElement
){
var
autoMerge
=
getValue
(
'
automerge
'
);
if
(
autoMerge
===
'
1
'
)
{
return
;
}
if
(
currentElement
.
id
!==
'
totp
'
){
var
placeholderElement
=
document
.
querySelector
(
"
label[id='
"
+
currentElement
.
id
+
"
LabelPlaceholder']
"
);
var
labelElement
=
document
.
querySelector
(
"
label[id='
"
+
currentElement
.
id
+
"
Label']
"
);
...
...
@@ -109,7 +196,11 @@ var inputBoxFocusIn = function(currentElement){
addClass
(
labelElement
,
"
hide
"
);
}
};
var
inputBoxFocusOut
=
function
(
currentElement
){
var
inputBoxFocusOut
=
function
(
currentElement
)
{
var
autoMerge
=
getValue
(
'
automerge
'
);
if
(
autoMerge
===
'
1
'
)
{
return
;
}
if
(
currentElement
.
id
!==
'
totp
'
){
var
placeholderElement
=
document
.
querySelector
(
"
label[id='
"
+
currentElement
.
id
+
"
LabelPlaceholder']
"
);
var
labelElement
=
document
.
querySelector
(
"
label[id='
"
+
currentElement
.
id
+
"
Label']
"
);
...
...
This diff is collapsed.
Click to expand it.
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment
Menu
Explore
Projects
Groups
Topics
Snippets