updates google sign in function
parent
2abe2298c6
commit
7ceb405f14
|
|
@ -7,11 +7,14 @@
|
|||
<!-- End Required meta tags -->
|
||||
<title>不來梅短網址管理系統</title>
|
||||
<!-- BEGIN BASE JS -->
|
||||
<script src="https://accounts.google.com/gsi/client" async defer></script>
|
||||
<script src="assets/vendor/jquery/jquery.min.js"></script>
|
||||
<script src="assets/vendor/jquery.cookie/jquery.cookie.js"></script>
|
||||
<script src="assets/javascript/sha256.js"></script>
|
||||
<script src="assets/vendor/bootstrap/js/popper.min.js"></script>
|
||||
<script src="assets/vendor/bootstrap/js/bootstrap.min.js"></script>
|
||||
<script src="assets/vendor/bootstrap/js/bootstrap.min.js"></script>
|
||||
<script src="assets/vendor/busy-load/app.min.js"></script>
|
||||
<link href="assets/vendor/busy-load/app.min.css" rel="stylesheet" />
|
||||
<!-- END BASE JS -->
|
||||
<!-- Favicons -->
|
||||
<link rel="apple-touch-icon" sizes="144x144" href="assets/apple-touch-icon.png">
|
||||
|
|
@ -68,6 +71,7 @@
|
|||
})(jQuery, document);
|
||||
|
||||
$(document).ready(function () {
|
||||
$.busyLoadSetup({ animation: "fade", background: "rgba(255, 152, 0, 0.75)" });
|
||||
|
||||
if ($.cookie("id") != null) {
|
||||
$("#inputUser").val($.cookieKey("id", "id"));
|
||||
|
|
@ -111,6 +115,73 @@
|
|||
return false;
|
||||
}
|
||||
</script>
|
||||
<script>
|
||||
function parseJwt(token) {
|
||||
var base64Url = token.split('.')[1];
|
||||
var base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
|
||||
var jsonPayload = decodeURIComponent(atob(base64).split('').map(function (c) {
|
||||
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
|
||||
}).join(''));
|
||||
|
||||
return JSON.parse(jsonPayload);
|
||||
};
|
||||
|
||||
function handleCredentialResponse(response) {
|
||||
$.busyLoadFull("show", {
|
||||
spinner: "circles"
|
||||
});
|
||||
|
||||
//console.log("Encoded JWT ID token: " + response.credential);
|
||||
//console.log("Encoded JWT ID token: " + response.credential);
|
||||
var jwt = response.credential;
|
||||
var rem = "N";
|
||||
|
||||
if ($("#remember-me").prop("checked")) {
|
||||
rem = "Y";
|
||||
}
|
||||
|
||||
var formData = {
|
||||
jwt: jwt,
|
||||
rem: rem
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
url: "api/validGoogleLogin.ashx",
|
||||
type: "POST",
|
||||
data: formData,
|
||||
success: function (data, textStatus, jqXHR) {
|
||||
if (data.ret == "yes") {
|
||||
location.href = "projects-management.aspx";
|
||||
} else {
|
||||
alert(data.message);
|
||||
}
|
||||
|
||||
$.busyLoadFull("hide");
|
||||
},
|
||||
error: function (jqXHR, textStatus, errorThrown) {
|
||||
alert('网絡或伺服器发生错误,请稍后重试!');
|
||||
$.busyLoadFull("hide");
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
window.onload = function () {
|
||||
google.accounts.id.initialize({
|
||||
client_id: "744443172891-jmgcl4phchbvi7a7l2b0dlf0iqeeh3so.apps.googleusercontent.com",
|
||||
callback: handleCredentialResponse
|
||||
});
|
||||
google.accounts.id.renderButton(
|
||||
document.getElementById("buttonDiv"),
|
||||
{ theme: "outline", size: "large", width: "356" } // customization attributes
|
||||
);
|
||||
//google.accounts.id.prompt(); // also display the One Tap dialog
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<!-- .auth -->
|
||||
|
|
@ -152,6 +223,10 @@
|
|||
<button class="btn btn-lg btn-primary btn-block" type="submit">Sign In</button>
|
||||
</div>
|
||||
<!-- /.form-group -->
|
||||
<div class="form-group">
|
||||
<div id="buttonDiv">
|
||||
</div>
|
||||
</div>
|
||||
<!-- .form-group -->
|
||||
<div class="form-group text-center">
|
||||
<div class="custom-control custom-control-inline custom-checkbox">
|
||||
|
|
|
|||
|
|
@ -84,6 +84,17 @@ public class userData : IHttpHandler, IReadOnlySessionState {
|
|||
|
||||
userObj.user_type = type;
|
||||
|
||||
string user_sql = string.Format("select * from users where user_email = '{0}' and user_uid <> '{1}' and user_onjob = 'Y'", sys_email, user_uid);
|
||||
autoBindDataTable objUserSQL = new autoBindDataTable(user_sql);
|
||||
|
||||
if (objUserSQL.dataRows.Count > 0) {
|
||||
objRet.ret = "no";
|
||||
objRet.err_code = "0011";
|
||||
objRet.message = "此Email已經有人使用! ";
|
||||
json.WriteObject(context.Response.OutputStream, objRet);
|
||||
return;
|
||||
}
|
||||
|
||||
if (sys_pwd != "") {
|
||||
userObj.user_pwd = sys_pwd;
|
||||
}
|
||||
|
|
@ -129,6 +140,17 @@ public class userData : IHttpHandler, IReadOnlySessionState {
|
|||
}
|
||||
|
||||
if (method == "add") {
|
||||
string user_sql = string.Format("select * from users where user_email = '{0}' and user_onjob = 'Y'", sys_email);
|
||||
autoBindDataTable objUserSQL = new autoBindDataTable(user_sql);
|
||||
|
||||
if (objUserSQL.dataRows.Count > 0) {
|
||||
objRet.ret = "no";
|
||||
objRet.err_code = "0011";
|
||||
objRet.message = "此Email已經有人使用! ";
|
||||
json.WriteObject(context.Response.OutputStream, objRet);
|
||||
return;
|
||||
}
|
||||
|
||||
if (type == "N")
|
||||
{
|
||||
userSQL = new autoBindDataTable(string.Format("select * from users where user_id = '{0}'", elab_select));
|
||||
|
|
|
|||
|
|
@ -0,0 +1,153 @@
|
|||
<%@ WebHandler Language="C#" Class="validGoogleLogin" %>
|
||||
|
||||
using System;
|
||||
using System.Web;
|
||||
using Google.Apis.Auth;
|
||||
using System.Runtime.Serialization.Json;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System.Web.Services.Protocols;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Web.SessionState;
|
||||
using System.Data;
|
||||
using System.Threading.Tasks;
|
||||
using System.Threading;
|
||||
using System.Collections.Generic;
|
||||
|
||||
public class validGoogleLogin : System.Web.HttpTaskAsyncHandler {
|
||||
|
||||
public override async System.Threading.Tasks.Task ProcessRequestAsync(HttpContext context) {
|
||||
result objRet = new result();
|
||||
DataContractJsonSerializer json = new DataContractJsonSerializer(objRet.GetType());
|
||||
context.Response.ContentType = "application/json;charset=utf-8";
|
||||
|
||||
string jwt = (context.Request["jwt"] == null) ? "" : context.Request["jwt"].ToString();//回傳憑證
|
||||
string remember = (context.Request["rem"] == null) ? "N" : context.Request["rem"].ToString();
|
||||
|
||||
if (jwt == "") {
|
||||
|
||||
objRet.ret = "no";
|
||||
objRet.err_code = "0001";
|
||||
objRet.message = "無JWT資料可以登入!";
|
||||
json.WriteObject(context.Response.OutputStream, objRet);
|
||||
return;
|
||||
}
|
||||
|
||||
//validate it using Google.Apis.Auth (null if invalid)
|
||||
//var validPayload = await GoogleJsonWebSignature.ValidateAsync(jwt);
|
||||
GoogleJsonWebSignature.Payload payload = await ValidateGoogleTokenAsync(jwt);
|
||||
|
||||
if (payload == null) {
|
||||
objRet.ret = "no";
|
||||
objRet.err_code = "0002";
|
||||
objRet.message = "JWT驗證失敗!";
|
||||
json.WriteObject(context.Response.OutputStream, objRet);
|
||||
return;
|
||||
}
|
||||
string googleID = System.Web.Configuration.WebConfigurationManager.AppSettings["googleOAuthID"].ToString();
|
||||
string audience = payload.Audience.ToString();
|
||||
|
||||
if (audience != googleID) {
|
||||
objRet.ret = "no";
|
||||
objRet.err_code = "0003";
|
||||
objRet.message = "JWT驗證失敗!";
|
||||
json.WriteObject(context.Response.OutputStream, objRet);
|
||||
return;
|
||||
}
|
||||
|
||||
string userId = payload.Subject;
|
||||
string email = payload.Email;
|
||||
string name = payload.Name;
|
||||
|
||||
string user_sql = string.Format("select * from users where user_email = '{0}' and user_onjob = 'Y'", email);
|
||||
autoBindDataTable objUser = new autoBindDataTable(user_sql);
|
||||
|
||||
if (objUser.dataRows.Count == 0) {
|
||||
objRet.ret = "no";
|
||||
objRet.err_code = "0004";
|
||||
objRet.message = "無此Email帳號於PRM系統中,請直屬主管加入!";
|
||||
json.WriteObject(context.Response.OutputStream, objRet);
|
||||
return;
|
||||
}
|
||||
|
||||
string token_key = CreateRandomCode(36);
|
||||
string user_uid = objUser.dataRows[0]["user_uid"].ToString();
|
||||
string id = objUser.dataRows[0]["user_id"].ToString();
|
||||
|
||||
autoBindDataTable dataToken = new autoBindDataTable("select * from token where token_sn = -1");
|
||||
DataRow rowToken = dataToken.newRow;
|
||||
dataToken.dataRows.Add(rowToken);
|
||||
rowToken["token_key"] = token_key;
|
||||
rowToken["user_uid"] = user_uid;
|
||||
rowToken["token_isremember"] = remember;
|
||||
rowToken["token_expireddate"] = DateTime.Now.AddMinutes(60);
|
||||
|
||||
|
||||
HttpCookie tokenCookie = new HttpCookie("token");
|
||||
HttpCookie idCookie = new HttpCookie("id");
|
||||
tokenCookie["token"] = token_key;
|
||||
tokenCookie["uid"] = user_uid;
|
||||
idCookie["id"] = id;
|
||||
|
||||
idCookie.Expires = DateTime.Now.AddDays(31);
|
||||
|
||||
if (remember == "Y") {
|
||||
tokenCookie.Expires = DateTime.Now.AddDays(10);
|
||||
rowToken["token_expireddate"] = DateTime.Now.AddDays(10);
|
||||
}
|
||||
|
||||
dataToken.updateDataTable();
|
||||
context.Response.Cookies.Add(tokenCookie);
|
||||
context.Response.Cookies.Add(idCookie);
|
||||
|
||||
objRet.ret = "yes";
|
||||
json.WriteObject(context.Response.OutputStream, objRet);
|
||||
}
|
||||
|
||||
private static async Task<GoogleJsonWebSignature.Payload> ValidateGoogleTokenAsync(string idToken)
|
||||
{
|
||||
try
|
||||
{
|
||||
var payload = await GoogleJsonWebSignature.ValidateAsync(idToken);
|
||||
|
||||
if (payload == null || string.IsNullOrEmpty(payload.Email))
|
||||
throw new UnauthorizedAccessException("Invalid Google Token");
|
||||
|
||||
return payload;
|
||||
}
|
||||
catch (Exception ex){
|
||||
string exM = ex.Message;
|
||||
throw new UnauthorizedAccessException("Invalid Google Token");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public string CreateRandomCode(int Number)
|
||||
{
|
||||
string allChar = "0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z";
|
||||
string[] allCharArray = allChar.Split(',');
|
||||
string randomCode = "";
|
||||
|
||||
Random rand = new Random(Guid.NewGuid().GetHashCode());
|
||||
for (int i = 0; i <= Number - 1; i++)
|
||||
{
|
||||
int t = rand.Next(allCharArray.Length);
|
||||
randomCode += allCharArray[t];
|
||||
}
|
||||
return randomCode;
|
||||
}
|
||||
|
||||
public class result {
|
||||
public string ret = "no";
|
||||
public string err_code = "0000";
|
||||
public string message = "";
|
||||
}
|
||||
|
||||
public bool IsReusable {
|
||||
get {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,285 @@
|
|||
/**
|
||||
* Spinners
|
||||
*
|
||||
* @see http://tobiasahlin.com/spinkit/
|
||||
*/
|
||||
.spinner-cube-grid {
|
||||
width: 40px;
|
||||
height: 40px; }
|
||||
.spinner-cube-grid .sk-cube {
|
||||
width: 33%;
|
||||
height: 33%;
|
||||
background-color: #333;
|
||||
float: left;
|
||||
-webkit-animation: sk-cubeGridScaleDelay 1.3s infinite ease-in-out;
|
||||
animation: sk-cubeGridScaleDelay 1.3s infinite ease-in-out; }
|
||||
.spinner-cube-grid .sk-cube1 {
|
||||
-webkit-animation-delay: 0.2s;
|
||||
animation-delay: 0.2s; }
|
||||
.spinner-cube-grid .sk-cube2 {
|
||||
-webkit-animation-delay: 0.3s;
|
||||
animation-delay: 0.3s; }
|
||||
.spinner-cube-grid .sk-cube3 {
|
||||
-webkit-animation-delay: 0.4s;
|
||||
animation-delay: 0.4s; }
|
||||
.spinner-cube-grid .sk-cube4 {
|
||||
-webkit-animation-delay: 0.1s;
|
||||
animation-delay: 0.1s; }
|
||||
.spinner-cube-grid .sk-cube5 {
|
||||
-webkit-animation-delay: 0.2s;
|
||||
animation-delay: 0.2s; }
|
||||
.spinner-cube-grid .sk-cube6 {
|
||||
-webkit-animation-delay: 0.3s;
|
||||
animation-delay: 0.3s; }
|
||||
.spinner-cube-grid .sk-cube7 {
|
||||
-webkit-animation-delay: 0s;
|
||||
animation-delay: 0s; }
|
||||
.spinner-cube-grid .sk-cube8 {
|
||||
-webkit-animation-delay: 0.1s;
|
||||
animation-delay: 0.1s; }
|
||||
.spinner-cube-grid .sk-cube9 {
|
||||
-webkit-animation-delay: 0.2s;
|
||||
animation-delay: 0.2s; }
|
||||
@-webkit-keyframes sk-cubeGridScaleDelay {
|
||||
0%, 70%, 100% {
|
||||
-webkit-transform: scale3D(1, 1, 1);
|
||||
transform: scale3D(1, 1, 1); }
|
||||
35% {
|
||||
-webkit-transform: scale3D(0, 0, 1);
|
||||
transform: scale3D(0, 0, 1); } }
|
||||
@keyframes sk-cubeGridScaleDelay {
|
||||
0%, 70%, 100% {
|
||||
-webkit-transform: scale3D(1, 1, 1);
|
||||
transform: scale3D(1, 1, 1); }
|
||||
35% {
|
||||
-webkit-transform: scale3D(0, 0, 1);
|
||||
transform: scale3D(0, 0, 1); } }
|
||||
.spinner-circle-line {
|
||||
margin: 10px auto 0;
|
||||
width: 70px;
|
||||
text-align: center; }
|
||||
.spinner-circle-line > div {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
background-color: #333;
|
||||
border-radius: 100%;
|
||||
display: inline-block;
|
||||
-webkit-animation: sk-bouncedelay 1.4s infinite ease-in-out both;
|
||||
animation: sk-bouncedelay 1.4s infinite ease-in-out both; }
|
||||
.spinner-circle-line .bounce1 {
|
||||
-webkit-animation-delay: -0.32s;
|
||||
animation-delay: -0.32s; }
|
||||
.spinner-circle-line .bounce2 {
|
||||
-webkit-animation-delay: -0.16s;
|
||||
animation-delay: -0.16s; }
|
||||
@-webkit-keyframes sk-bouncedelay {
|
||||
0%, 80%, 100% {
|
||||
-webkit-transform: scale(0); }
|
||||
40% {
|
||||
-webkit-transform: scale(1); } }
|
||||
@keyframes sk-bouncedelay {
|
||||
0%, 80%, 100% {
|
||||
-webkit-transform: scale(0);
|
||||
transform: scale(0); }
|
||||
40% {
|
||||
-webkit-transform: scale(1);
|
||||
transform: scale(1); } }
|
||||
.spinner-circles {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
position: relative;
|
||||
text-align: center;
|
||||
-webkit-animation: sk-rotate 2.0s infinite linear;
|
||||
animation: sk-rotate 2.0s infinite linear; }
|
||||
.dot1, .dot2 {
|
||||
width: 60%;
|
||||
height: 60%;
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
background-color: #333;
|
||||
border-radius: 100%;
|
||||
-webkit-animation: sk-bounce 2.0s infinite ease-in-out;
|
||||
animation: sk-bounce 2.0s infinite ease-in-out; }
|
||||
.dot2 {
|
||||
top: auto;
|
||||
bottom: 0;
|
||||
-webkit-animation-delay: -1.0s;
|
||||
animation-delay: -1.0s; }
|
||||
@-webkit-keyframes sk-rotate {
|
||||
100% {
|
||||
-webkit-transform: rotate(360deg); } }
|
||||
@keyframes sk-rotate {
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
-webkit-transform: rotate(360deg); } }
|
||||
@-webkit-keyframes sk-bounce {
|
||||
0%, 100% {
|
||||
-webkit-transform: scale(0); }
|
||||
50% {
|
||||
-webkit-transform: scale(1); } }
|
||||
@keyframes sk-bounce {
|
||||
0%, 100% {
|
||||
transform: scale(0);
|
||||
-webkit-transform: scale(0); }
|
||||
50% {
|
||||
transform: scale(1);
|
||||
-webkit-transform: scale(1); } }
|
||||
/* Cube */
|
||||
.spinner-cube {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
background-color: #333;
|
||||
margin: 100px auto;
|
||||
-webkit-animation: sk-rotateplane 1.2s infinite ease-in-out;
|
||||
animation: sk-rotateplane 1.2s infinite ease-in-out; }
|
||||
@-webkit-keyframes sk-rotateplane {
|
||||
0% {
|
||||
-webkit-transform: perspective(120px); }
|
||||
50% {
|
||||
-webkit-transform: perspective(120px) rotateY(180deg); }
|
||||
100% {
|
||||
-webkit-transform: perspective(120px) rotateY(180deg) rotateX(180deg); } }
|
||||
@keyframes sk-rotateplane {
|
||||
0% {
|
||||
transform: perspective(120px) rotateX(0deg) rotateY(0deg);
|
||||
-webkit-transform: perspective(120px) rotateX(0deg) rotateY(0deg); }
|
||||
50% {
|
||||
transform: perspective(120px) rotateX(-180.1deg) rotateY(0deg);
|
||||
-webkit-transform: perspective(120px) rotateX(-180.1deg) rotateY(0deg); }
|
||||
100% {
|
||||
transform: perspective(120px) rotateX(-180deg) rotateY(-179.9deg);
|
||||
-webkit-transform: perspective(120px) rotateX(-180deg) rotateY(-179.9deg); } }
|
||||
.spinner-cubes {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
position: relative; }
|
||||
.cube1, .cube2 {
|
||||
background-color: #333;
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
-webkit-animation: sk-cubemove 1.8s infinite ease-in-out;
|
||||
animation: sk-cubemove 1.8s infinite ease-in-out; }
|
||||
.cube2 {
|
||||
-webkit-animation-delay: -0.9s;
|
||||
animation-delay: -0.9s; }
|
||||
@-webkit-keyframes sk-cubemove {
|
||||
25% {
|
||||
-webkit-transform: translateX(42px) rotate(-90deg) scale(0.5); }
|
||||
50% {
|
||||
-webkit-transform: translateX(42px) translateY(42px) rotate(-180deg); }
|
||||
75% {
|
||||
-webkit-transform: translateX(0px) translateY(42px) rotate(-270deg) scale(0.5); }
|
||||
100% {
|
||||
-webkit-transform: rotate(-360deg); } }
|
||||
@keyframes sk-cubemove {
|
||||
25% {
|
||||
transform: translateX(42px) rotate(-90deg) scale(0.5);
|
||||
-webkit-transform: translateX(42px) rotate(-90deg) scale(0.5); }
|
||||
50% {
|
||||
transform: translateX(42px) translateY(42px) rotate(-179deg);
|
||||
-webkit-transform: translateX(42px) translateY(42px) rotate(-179deg); }
|
||||
50.1% {
|
||||
transform: translateX(42px) translateY(42px) rotate(-180deg);
|
||||
-webkit-transform: translateX(42px) translateY(42px) rotate(-180deg); }
|
||||
75% {
|
||||
transform: translateX(0px) translateY(42px) rotate(-270deg) scale(0.5);
|
||||
-webkit-transform: translateX(0px) translateY(42px) rotate(-270deg) scale(0.5); }
|
||||
100% {
|
||||
transform: rotate(-360deg);
|
||||
-webkit-transform: rotate(-360deg); } }
|
||||
.spinner-pump {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
position: relative; }
|
||||
.double-bounce1, .double-bounce2 {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 50%;
|
||||
background-color: #333;
|
||||
opacity: 0.6;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
-webkit-animation: sk-bounce 2.0s infinite ease-in-out;
|
||||
animation: sk-bounce 2.0s infinite ease-in-out; }
|
||||
.double-bounce2 {
|
||||
-webkit-animation-delay: -1.0s;
|
||||
animation-delay: -1.0s; }
|
||||
@-webkit-keyframes sk-bounce {
|
||||
0%, 100% {
|
||||
-webkit-transform: scale(0); }
|
||||
50% {
|
||||
-webkit-transform: scale(1); } }
|
||||
@keyframes sk-bounce {
|
||||
0%, 100% {
|
||||
transform: scale(0);
|
||||
-webkit-transform: scale(0); }
|
||||
50% {
|
||||
transform: scale(1);
|
||||
-webkit-transform: scale(1); } }
|
||||
/* Pulsar */
|
||||
.spinner-pulsar {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
background-color: #333;
|
||||
border-radius: 100%;
|
||||
-webkit-animation: sk-scaleout 1.0s infinite ease-in-out;
|
||||
animation: sk-scaleout 1.0s infinite ease-in-out; }
|
||||
@-webkit-keyframes sk-scaleout {
|
||||
0% {
|
||||
-webkit-transform: scale(0); }
|
||||
100% {
|
||||
-webkit-transform: scale(1);
|
||||
opacity: 0; } }
|
||||
@keyframes sk-scaleout {
|
||||
0% {
|
||||
-webkit-transform: scale(0);
|
||||
transform: scale(0); }
|
||||
100% {
|
||||
-webkit-transform: scale(1);
|
||||
transform: scale(1);
|
||||
opacity: 0; } }
|
||||
/* Accordion */
|
||||
.spinner-accordion {
|
||||
margin: 100px auto;
|
||||
width: 50px;
|
||||
height: 40px;
|
||||
text-align: center;
|
||||
font-size: 10px; }
|
||||
.spinner-accordion > div {
|
||||
background-color: #333;
|
||||
height: 100%;
|
||||
width: 6px;
|
||||
display: inline-block;
|
||||
-webkit-animation: sk-stretchdelay 1.2s infinite ease-in-out;
|
||||
animation: sk-stretchdelay 1.2s infinite ease-in-out; }
|
||||
.spinner-accordion.rect2 {
|
||||
-webkit-animation-delay: -1.1s;
|
||||
animation-delay: -1.1s; }
|
||||
.spinner-accordion .rect3 {
|
||||
-webkit-animation-delay: -1.0s;
|
||||
animation-delay: -1.0s; }
|
||||
.spinner-accordion .rect4 {
|
||||
-webkit-animation-delay: -0.9s;
|
||||
animation-delay: -0.9s; }
|
||||
.spinner-accordion.rect5 {
|
||||
-webkit-animation-delay: -0.8s;
|
||||
animation-delay: -0.8s; }
|
||||
@-webkit-keyframes sk-stretchdelay {
|
||||
0%, 40%, 100% {
|
||||
-webkit-transform: scaleY(0.4); }
|
||||
20% {
|
||||
-webkit-transform: scaleY(1); } }
|
||||
@keyframes sk-stretchdelay {
|
||||
0%, 40%, 100% {
|
||||
transform: scaleY(0.4);
|
||||
-webkit-transform: scaleY(0.4); }
|
||||
20% {
|
||||
transform: scaleY(1);
|
||||
-webkit-transform: scaleY(1); } }
|
||||
.no-scroll {
|
||||
overflow: hidden; }
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -4,6 +4,10 @@
|
|||
https://go.microsoft.com/fwlink/?LinkId=169433
|
||||
-->
|
||||
<configuration>
|
||||
<appSettings>
|
||||
<add key="googleOAuthID" value="744443172891-jmgcl4phchbvi7a7l2b0dlf0iqeeh3so.apps.googleusercontent.com" />
|
||||
<add key="googleOAuthKey" value="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" />
|
||||
</appSettings>
|
||||
<connectionStrings>
|
||||
<add name="DBConnectionString" connectionString="Data Source=sql.bremen.com.tw;Initial Catalog=short_url;User ID=short_url;Password=B1ba68^n;Max Pool Size=17500;Connection Lifetime=3;" providerName="System.Data.SqlClient" />
|
||||
<add name="ElabConnectionString" connectionString="Data Source=sql.bremen.com.tw;Initial Catalog=elab;User ID=elab;Password=2#2k9Vfg;" />
|
||||
|
|
|
|||
Loading…
Reference in New Issue