Add database authentication

This commit is contained in:
Aaron Lee 2021-09-25 13:31:36 +08:00
parent 18f62768e0
commit 16250857df
8 changed files with 77 additions and 101 deletions

1
.gitignore vendored
View file

@ -4,3 +4,4 @@ test.py
demoData/* demoData/*
dummyData/* dummyData/*
users.txt users.txt
__pycache__/*

95
app.py
View file

@ -42,8 +42,8 @@ def check_login_status():
def check_permission(): def check_permission():
return (db.child('Users').child(session['uid']).child('permission').get().val() == 'admin' and return (db.child('Users').child(session['uid']).child('permission').get(session['token']).val() == 'admin' and
db.child("Users").child(session['uid']).child("showUpload").get().val() == '1') db.child("Users").child(session['uid']).child("showUpload").get(session['token']).val() == '1')
def verify_recaptcha(response): def verify_recaptcha(response):
@ -62,12 +62,12 @@ def manageProcess(fCommand, fData):
return redirect('/logout') return redirect('/logout')
# this is to fix a bug where pyrebase doesnt load the first request # this is to fix a bug where pyrebase doesnt load the first request
db.child("Users").child( db.child("Users").child(
session['uid']).child("permission").get().val() session['uid']).child("permission").get(session['token']).val()
# end bug fix # end bug fix
pl = db.child("Users").child( pl = db.child("Users").child(
session['uid']).child("permission").get().val() session['uid']).child("permission").get(session['token']).val()
if pl == 'admin': if pl == 'admin':
homerooms = db.child("Homerooms").get().val() homerooms = db.child("Homerooms").get(session['token']).val()
currRoom = [] currRoom = []
if fCommand == "admin": if fCommand == "admin":
currRoom = fData[0].split("^") currRoom = fData[0].split("^")
@ -94,15 +94,15 @@ def manageProcess(fCommand, fData):
return render_template('admin.html', homerooms=homerooms, absData=absData, return render_template('admin.html', homerooms=homerooms, absData=absData,
homeroomCode=currRoom, homeroomData=homeroomData, currDate=currDate, periods=['m', '1', '2', '3', '4', homeroomCode=currRoom, homeroomData=homeroomData, currDate=currDate, periods=['m', '1', '2', '3', '4',
'n', '5', '6', '7', '8', '9'], showUpload=db.child("Users").child( 'n', '5', '6', '7', '8', '9'], showUpload=db.child("Users").child(
session['uid']).child("showUpload").get().val()) session['uid']).child("showUpload").get(session['token']).val())
elif pl == 'group': elif pl == 'group':
classes = db.child("Users").child( classes = db.child("Users").child(
session['uid']).child("class").get().val() session['uid']).child("class").get(session['token']).val()
cclass = {} cclass = {}
cateData = {} cateData = {}
for i in classes: for i in classes:
cateData = db.child("Classes").child( cateData = db.child("Classes").child(
"GP_Class").child(i).get().val() "GP_Class").child(i).get(session['token']).val()
cclass = { cclass = {
"name": cateData['Class'][classes[i]]['name'], "name": cateData['Class'][classes[i]]['name'],
"category": i, "category": i,
@ -114,7 +114,8 @@ def manageProcess(fCommand, fData):
absData = {} absData = {}
for h in homerooms: for h in homerooms:
h = h.split('^') h = h.split('^')
hrData = db.child("Homerooms").child(h[0]).child(h[1]).get().val() hrData = db.child("Homerooms").child(
h[0]).child(h[1]).get(session['token']).val()
tmpAbsData = hrData['Absent'] tmpAbsData = hrData['Absent']
hrData.pop('Absent') hrData.pop('Absent')
if 'placeholder' in hrData: if 'placeholder' in hrData:
@ -188,9 +189,9 @@ def manageProcess(fCommand, fData):
return render_template('group_teach.html', cclass=cclass, absData=absData, dow=dow, currDate=currDate, tmpAbsData=tmpAbsData, confirmed=confirmed) return render_template('group_teach.html', cclass=cclass, absData=absData, dow=dow, currDate=currDate, tmpAbsData=tmpAbsData, confirmed=confirmed)
elif pl == 'homeroom': elif pl == 'homeroom':
homeroom = db.child("Users").child( homeroom = db.child("Users").child(
session['uid']).child("homeroom").get().val().split('^') session['uid']).child("homeroom").get(session['token']).val().split('^')
homeroomData = db.child("Homerooms").child(homeroom[0]).child( homeroomData = db.child("Homerooms").child(homeroom[0]).child(
homeroom[1]).get().val() homeroom[1]).get(session['token']).val()
times = OrderedDict({ times = OrderedDict({
'm': '00:00', 'm': '00:00',
'1': '08:15', '1': '08:15',
@ -230,11 +231,11 @@ def manageProcess(fCommand, fData):
return redirect('/logout') return redirect('/logout')
@ app.route('/', methods=['GET']) @ app.route('/', methods=['GET', 'POST'])
def index(): def index():
if request.method == 'GET': if request.method == 'GET':
if check_login_status(): if check_login_status():
return render_template('login.html', error=False) return render_template('login.html')
return redirect('/manage') return redirect('/manage')
elif request.method == 'POST': elif request.method == 'POST':
if check_login_status(): if check_login_status():
@ -250,9 +251,13 @@ def index():
session['loginTime'] = datetime.now(tz) session['loginTime'] = datetime.now(tz)
return redirect('/manage') return redirect('/manage')
else: else:
return render_template('login.html', error=True) flash(
'reCAPTCHA 錯誤,請稍後再試一次<br>reCAPTCHA Failed. Please try again later.')
return redirect('/')
except Exception as e: except Exception as e:
return render_template('login.html', error=True) flash(
'帳號或密碼錯誤,請重新輸入<br>Incorrect username or password')
return redirect('/')
else: else:
return redirect('/manage') return redirect('/manage')
@ -281,16 +286,16 @@ def group_teach_publish():
if (check_login_status()): if (check_login_status()):
return redirect('/logout') return redirect('/logout')
classes = db.child("Users").child( classes = db.child("Users").child(
session['uid']).child("class").get().val() session['uid']).child("class").get(session['token']).val()
cclass = {} cclass = {}
for i in classes: for i in classes:
cclass = { cclass = {
"name": db.child("Classes").child("GP_Class").child(i).child( "name": db.child("Classes").child("GP_Class").child(i).child(
"Class").child(classes[i]).child("name").get().val(), "Class").child(classes[i]).child("name").get(session['token']).val(),
"category": i, "category": i,
"class_id": classes[i], "class_id": classes[i],
"homerooms": db.child("Classes").child( "homerooms": db.child("Classes").child(
"GP_Class").child(i).child("Homerooms").get().val() "GP_Class").child(i).child("Homerooms").get(session['token']).val()
} }
date = request.form['date'] date = request.form['date']
period = request.form['period'] period = request.form['period']
@ -307,28 +312,28 @@ def group_teach_publish():
with open(os.path.join('temp', rand), "wb") as fh: with open(os.path.join('temp', rand), "wb") as fh:
fh.write(base64.decodebytes(signature)) fh.write(base64.decodebytes(signature))
storage.child(os.path.join('signatures', rand) storage.child(os.path.join('signatures', rand)
).put(os.path.join('temp', rand)) ).put(os.path.join('temp', rand), session['token'])
formData.pop('signatureData') formData.pop('signatureData')
formData.pop('date') formData.pop('date')
formData.pop('period') formData.pop('period')
for i in formData: for i in formData:
i = i.split('^') i = i.split('^')
db.child("Homerooms").child(i[1]).child(i[2]).child( db.child("Homerooms").child(i[1]).child(i[2]).child(
"Absent").child(date).child(period).update({i[3]: int(i[0])}) "Absent").child(date).child(period).update({i[3]: int(i[0])}, session['token'])
for h in cclass['homerooms']: for h in cclass['homerooms']:
h = h.split('^') h = h.split('^')
db.child("Homerooms").child(h[0]).child(h[1]).child( db.child("Homerooms").child(h[0]).child(h[1]).child(
"Absent").child(date).child(period).child("signature").update({cclass['class_id']: str(storage.child(os.path.join('signatures', rand)).get_url(None))}) "Absent").child(date).child(period).child("signature").update({cclass['class_id']: str(storage.child(os.path.join('signatures', rand)).get_url(None))}, session['token'])
db.child("Homerooms").child(h[0]).child(h[1]).child( db.child("Homerooms").child(h[0]).child(h[1]).child(
"Absent").child(date).child(period).child("names").child(cclass['class_id']).set(cclass['name']) "Absent").child(date).child(period).child("names").child(cclass['class_id']).set(cclass['name'], session['token'])
currPeriodData = db.child("Homerooms").child(h[0]).child(h[1]).child( currPeriodData = db.child("Homerooms").child(h[0]).child(h[1]).child(
"Absent").child(date).child(period).get().val() "Absent").child(date).child(period).get(session['token']).val()
if 'notes' in currPeriodData: if 'notes' in currPeriodData:
db.child("Homerooms").child(h[0]).child(h[1]).child( db.child("Homerooms").child(h[0]).child(h[1]).child(
"Absent").child(date).child(period).update({'notes': currPeriodData['notes']+'; '+notes}) "Absent").child(date).child(period).update({'notes': currPeriodData['notes']+'; '+notes}, session['token'])
else: else:
db.child("Homerooms").child(h[0]).child(h[1]).child( db.child("Homerooms").child(h[0]).child(h[1]).child(
"Absent").child(date).child(period).update({'notes': notes}) "Absent").child(date).child(period).update({'notes': notes}, session['token'])
# upload notes # upload notes
os.remove(os.path.join('temp', rand)) os.remove(os.path.join('temp', rand))
@ -355,7 +360,7 @@ def homeroom_abs_publish():
with open(os.path.join('temp', rand), "wb") as fh: with open(os.path.join('temp', rand), "wb") as fh:
fh.write(base64.decodebytes(signature)) fh.write(base64.decodebytes(signature))
storage.child(os.path.join('signatures', rand) storage.child(os.path.join('signatures', rand)
).put(os.path.join('temp', rand)) ).put(os.path.join('temp', rand), session['token'])
formData.pop('signatureData') formData.pop('signatureData')
formData.pop('date') formData.pop('date')
formData.pop('homeroom') formData.pop('homeroom')
@ -363,11 +368,11 @@ def homeroom_abs_publish():
for i in formData: for i in formData:
i = i.split('^') i = i.split('^')
db.child("Homerooms").child(homeroom[0]).child( db.child("Homerooms").child(homeroom[0]).child(
homeroom[1]).child("Absent").child(date).child(period).update({i[1]: int(i[0])}) homeroom[1]).child("Absent").child(date).child(period).update({i[1]: int(i[0])}, session['token'])
db.child("Homerooms").child(homeroom[0]).child(homeroom[1]).child( db.child("Homerooms").child(homeroom[0]).child(homeroom[1]).child(
"Absent").child(date).child(period).update({'signature': str(storage.child(os.path.join('signatures', rand)).get_url(None))}) "Absent").child(date).child(period).update({'signature': str(storage.child(os.path.join('signatures', rand)).get_url(None))}, session['token'])
db.child("Homerooms").child(homeroom[0]).child(homeroom[1]).child( db.child("Homerooms").child(homeroom[0]).child(homeroom[1]).child(
"Absent").child(date).child(period).update({'notes': notes}) "Absent").child(date).child(period).update({'notes': notes}, session['token'])
os.remove(os.path.join('temp', rand)) os.remove(os.path.join('temp', rand))
return redirect('/manage') return redirect('/manage')
@ -386,9 +391,9 @@ def homeroom_confirm():
with open(os.path.join('temp', rand), "wb") as fh: with open(os.path.join('temp', rand), "wb") as fh:
fh.write(base64.decodebytes(signature)) fh.write(base64.decodebytes(signature))
storage.child(os.path.join('signatures', rand) storage.child(os.path.join('signatures', rand)
).put(os.path.join('temp', rand)) ).put(os.path.join('temp', rand), session['token'])
db.child("Homerooms").child(homeroom[0]).child(homeroom[1]).child("Absent").child(date).update( db.child("Homerooms").child(homeroom[0]).child(homeroom[1]).child("Absent").child(date).update(
{"confirm": str(storage.child(os.path.join('signatures', rand)).get_url(None))}) {"confirm": str(storage.child(os.path.join('signatures', rand)).get_url(None))}, session['token'])
os.remove(os.path.join('temp', rand)) os.remove(os.path.join('temp', rand))
return redirect('/manage') return redirect('/manage')
@ -421,7 +426,7 @@ def upload_homeroom():
}) })
else: else:
db.child("Homerooms").child(gradec).child( db.child("Homerooms").child(gradec).child(
classc).child(row['number']).set(row) classc).child(row['number']).set(row, session['token'])
# row['class'] row['number'] row['name'] row['eng_name'] # row['class'] row['number'] row['name'] row['eng_name']
os.remove(filepath) os.remove(filepath)
except Exception as e: except Exception as e:
@ -451,7 +456,7 @@ def upload_gp_classes():
break break
if j % 5 == 0: if j % 5 == 0:
db.child("Classes").child("GP_Class").child(csv_dict.columns[i+1]).child("Class").child( db.child("Classes").child("GP_Class").child(csv_dict.columns[i+1]).child("Class").child(
tmp_csv[j]).child("name").set(tmp_csv[j+1] + " : " + tmp_csv[j+2] + " (" + tmp_csv[j+3] + ")") tmp_csv[j]).child("name").set(tmp_csv[j+1] + " : " + tmp_csv[j+2] + " (" + tmp_csv[j+3] + ")", session['token'])
auth.create_user_with_email_and_password( auth.create_user_with_email_and_password(
tmp_csv[j] + "@group-attendance.fhjh.tp.edu.tw", tmp_csv[j+4]) tmp_csv[j] + "@group-attendance.fhjh.tp.edu.tw", tmp_csv[j+4])
user = auth.sign_in_with_email_and_password( user = auth.sign_in_with_email_and_password(
@ -462,7 +467,7 @@ def upload_gp_classes():
"class": { "class": {
csv_dict.columns[i+1]: tmp_csv[j], csv_dict.columns[i+1]: tmp_csv[j],
} }
}) }, session['token'])
os.remove(filepath) os.remove(filepath)
except Exception as e: except Exception as e:
os.remove(filepath) os.remove(filepath)
@ -490,11 +495,11 @@ def upload_stud_in_group():
headers = headers[1:] headers = headers[1:]
for h in headers: for h in headers:
db.child("Classes").child("GP_Class").child( db.child("Classes").child("GP_Class").child(
h).child("Homerooms").update({gradec+'^'+classc: 0}) h).child("Homerooms").update({gradec+'^'+classc: 0}, session['token'])
for row in csv_dict: for row in csv_dict:
for h in headers: for h in headers:
db.child("Homerooms").child(gradec).child(classc).child( db.child("Homerooms").child(gradec).child(classc).child(
row['number']).child("GP_Class").update({h: row[h]}) row['number']).child("GP_Class").update({h: row[h]}, session['token'])
os.remove(filepath) os.remove(filepath)
except Exception as e: except Exception as e:
os.remove(filepath) os.remove(filepath)
@ -525,14 +530,14 @@ def upload_period_list():
if not (periodCodes[j].endswith('-t')): if not (periodCodes[j].endswith('-t')):
if type(tmp_csv[j]) == float: if type(tmp_csv[j]) == float:
db.child("Classes").child("Homeroom").child(gradec).child(classc).child( db.child("Classes").child("Homeroom").child(gradec).child(classc).child(
str(i+1)).child(periodCodes[j]).update({'name': '--'}) str(i+1)).child(periodCodes[j]).update({'name': '--'}, session['token'])
else: else:
db.child("Classes").child("Homeroom").child(gradec).child(classc).child( db.child("Classes").child("Homeroom").child(gradec).child(classc).child(
str(i+1)).child(periodCodes[j]).update({'name': tmp_csv[j]}) str(i+1)).child(periodCodes[j]).update({'name': tmp_csv[j]}, session['token'])
if not(periodCodes[j] == 'm' or periodCodes[j] == 'n'): if not(periodCodes[j] == 'm' or periodCodes[j] == 'n'):
j += 1 j += 1
db.child("Classes").child("Homeroom").child(gradec).child(classc).child( db.child("Classes").child("Homeroom").child(gradec).child(classc).child(
str(i+1)).child(periodCodes[j-1]).update({'teacher': tmp_csv[j]}) str(i+1)).child(periodCodes[j-1]).update({'teacher': tmp_csv[j]}, session['token'])
os.remove(filepath) os.remove(filepath)
except Exception as e: except Exception as e:
os.remove(filepath) os.remove(filepath)
@ -555,19 +560,17 @@ def upload_dates():
with open(filepath) as file: with open(filepath) as file:
csv_dict = csv.DictReader(file) csv_dict = csv.DictReader(file)
headers = csv_dict.fieldnames headers = csv_dict.fieldnames
temp = db.child("Homerooms").get().val() temp = db.child("Homerooms").get(session['token']).val()
for row in csv_dict: for row in csv_dict:
for h in headers: for h in headers:
for t in temp: for t in temp:
for i in temp[t]: for i in temp[t]:
periodData = db.child("Classes").child( periodData = db.child("Classes").child(
"Homeroom").child(t).child(i).get().val() "Homeroom").child(t).child(i).get(session['token']).val()
db.child("Homerooms").child(t).child(i).child( db.child("Homerooms").child(t).child(i).child(
"Absent").child(h).update({"dow": row[h]}) "Absent").child(h).update({"dow": row[h]}, session['token'])
db.child("Homerooms").child(t).child(i).child( db.child("Homerooms").child(t).child(i).child(
"Absent").child(h).update( "Absent").child(h).update(periodData[int(row[h])], session['token'])
periodData[int(row[h])]
)
os.remove(filepath) os.remove(filepath)
except Exception as e: except Exception as e:
os.remove(filepath) os.remove(filepath)
@ -598,7 +601,7 @@ def upload_admin_acc():
'permission': 'admin', 'permission': 'admin',
'username': row['username'], 'username': row['username'],
'showUpload': row['permission'] 'showUpload': row['permission']
}) }, session['token'])
os.remove(filepath) os.remove(filepath)
except Exception as e: except Exception as e:
os.remove(filepath) os.remove(filepath)

View file

@ -5,7 +5,7 @@
<meta charset="utf-8"> <meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<title>Admin 管理員</title> <title>Admin 管理員 - Attendance 點名</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.1/dist/css/bootstrap.min.css" rel="stylesheet" <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.1/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-F3w7mX95PdgyTmZZMECAngseQB83DfGTowi0iMjiWaeVhAn4FJkqJByhZMI3AhiU" crossorigin="anonymous"> integrity="sha384-F3w7mX95PdgyTmZZMECAngseQB83DfGTowi0iMjiWaeVhAn4FJkqJByhZMI3AhiU" crossorigin="anonymous">
<link rel="stylesheet" href="/static/allpages.css"> <link rel="stylesheet" href="/static/allpages.css">
@ -199,15 +199,7 @@
<div id="loading" style="text-align:center; width:100%; display:none;"><img src="/static/loading.gif" alt="" <div id="loading" style="text-align:center; width:100%; display:none;"><img src="/static/loading.gif" alt=""
style="height:100%;" /> style="height:100%;" />
</div> </div>
<footer> {% include 'footer.html' %}
<hr>
<p style="text-align: center;">&copy; 2021 Attendance (β) | Made by <a target="_blank"
href="https://github.com/aaronleetw">Aaron Lee 李翊愷</a> for <a target="_blank"
href="https://www.fhjh.tp.edu.tw">Taipei Fuhsing Private School</a>
<br>
Consultants: Mr. Raymond Tsai 蔡瑋倫老師, Alvin Tsao 曹庭睿
</p>
</footer>
<script> <script>
var homerooms = {}; var homerooms = {};
{% for i in homerooms %} {% for i in homerooms %}

9
templates/footer.html Normal file
View file

@ -0,0 +1,9 @@
<footer>
<hr>
<p style="text-align: center;">&copy; 2021 Attendance (β) | Made by <a target="_blank"
href="https://github.com/aaronleetw">Aaron Lee 李翊愷</a> for <a target="_blank"
href="https://www.fhjh.tp.edu.tw">Taipei Fuhsing Private School</a>
<br>
Consultants: Mr. Raymond Tsai 蔡瑋倫老師, Alvin Tsao 曹庭睿
</p>
</footer>

View file

@ -5,7 +5,7 @@
<meta charset="utf-8"> <meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<title>Group 分組</title> <title>Group 分組 - Attendance 點名</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.1/dist/css/bootstrap.min.css" rel="stylesheet" <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.1/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-F3w7mX95PdgyTmZZMECAngseQB83DfGTowi0iMjiWaeVhAn4FJkqJByhZMI3AhiU" crossorigin="anonymous"> integrity="sha384-F3w7mX95PdgyTmZZMECAngseQB83DfGTowi0iMjiWaeVhAn4FJkqJByhZMI3AhiU" crossorigin="anonymous">
<link rel="stylesheet" href="/static/allpages.css"> <link rel="stylesheet" href="/static/allpages.css">
@ -188,18 +188,10 @@
document.getElementById('late^' + string).checked = false; document.getElementById('late^' + string).checked = false;
} }
</script> </script>
<div id="loading" style="text-align:center; width:100%; display:none;"><img src="/static/loading.gif" alt="" <div id="loading" style="text-align:center; width:100%; max-height:100%; display:none;"><img
style="width:100%;" /> src="/static/loading.gif" alt="" style="width:100%;" />
</div> </div>
<footer> {% include 'footer.html' %}
<hr>
<p style="text-align: center;">&copy; 2021 Attendance (β) | Made by <a target="_blank"
href="https://github.com/aaronleetw">Aaron Lee 李翊愷</a> for <a target="_blank"
href="https://www.fhjh.tp.edu.tw">Taipei Fuhsing Private School</a>
<br>
Consultants: Mr. Raymond Tsai 蔡瑋倫老師, Alvin Tsao 曹庭睿
</p>
</footer>
<script> <script>
function loadingAnimation() { function loadingAnimation() {
$("div.container").hide(); $("div.container").hide();

View file

@ -5,7 +5,7 @@
<meta charset="utf-8"> <meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<title>Homeroom 班級 {{homeroomCode[0]}}{{homeroomCode[1]}})</title> <title>Homeroom 班級 {{homeroomCode[0]}}{{homeroomCode[1]}}) - Attendance 點名</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.1/dist/css/bootstrap.min.css" rel="stylesheet" <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.1/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-F3w7mX95PdgyTmZZMECAngseQB83DfGTowi0iMjiWaeVhAn4FJkqJByhZMI3AhiU" crossorigin="anonymous"> integrity="sha384-F3w7mX95PdgyTmZZMECAngseQB83DfGTowi0iMjiWaeVhAn4FJkqJByhZMI3AhiU" crossorigin="anonymous">
<link rel="stylesheet" href="/static/allpages.css"> <link rel="stylesheet" href="/static/allpages.css">
@ -217,15 +217,7 @@
<div id="loading" style="text-align:center; width:100%; display:none;"><img src="/static/loading.gif" alt="" <div id="loading" style="text-align:center; width:100%; display:none;"><img src="/static/loading.gif" alt=""
style="height:100%;" /> style="height:100%;" />
</div> </div>
<footer> {% include 'footer.html' %}
<hr>
<p style="text-align: center;">&copy; 2021 Attendance (β) | Made by <a target="_blank"
href="https://github.com/aaronleetw">Aaron Lee 李翊愷</a> for <a target="_blank"
href="https://www.fhjh.tp.edu.tw">Taipei Fuhsing Private School</a>
<br>
Consultants: Mr. Raymond Tsai 蔡瑋倫老師, Alvin Tsao 曹庭睿
</p>
</footer>
<script> <script>
var signaturePad, hrCfrm = false; var signaturePad, hrCfrm = false;
var width = $(window).width(); var width = $(window).width();

View file

@ -4,7 +4,7 @@
<meta charset="utf-8"> <meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<title>Login | 登入</title> <title>Attendance 點名系統 (β)</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.1/dist/css/bootstrap.min.css" rel="stylesheet" <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.1/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-F3w7mX95PdgyTmZZMECAngseQB83DfGTowi0iMjiWaeVhAn4FJkqJByhZMI3AhiU" crossorigin="anonymous"> integrity="sha384-F3w7mX95PdgyTmZZMECAngseQB83DfGTowi0iMjiWaeVhAn4FJkqJByhZMI3AhiU" crossorigin="anonymous">
<link rel="stylesheet" href="/static/allpages.css"> <link rel="stylesheet" href="/static/allpages.css">
@ -51,12 +51,15 @@
<a target="_blank" href="https://policies.google.com/privacy">Privacy Policy</a> and <a target="_blank" href="https://policies.google.com/privacy">Privacy Policy</a> and
<a target="_blank" href="https://policies.google.com/terms">Terms of Service</a> apply. <a target="_blank" href="https://policies.google.com/terms">Terms of Service</a> apply.
</div> </div>
{% if error %} {% with messages = get_flashed_messages() %}
{% if messages %}
<div class="alert alert-danger" role="alert"> <div class="alert alert-danger" role="alert">
帳號或密碼錯誤,請重新輸入<br> {% for message in messages %}
Incorrect username or password {% autoescape false %}{{message}}{% endautoescape %}
{% endfor %}
</div> </div>
{% endif %} {% endif %}
{% endwith %}
</div> </div>
<div class="col"></div> <div class="col"></div>
</div> </div>
@ -64,15 +67,7 @@
<div id="loading" style="text-align:center; width:100%; display:none;"><img src="/static/loading.gif" alt="" <div id="loading" style="text-align:center; width:100%; display:none;"><img src="/static/loading.gif" alt=""
style="height:100%;" /> style="height:100%;" />
</div> </div>
<footer> {% include 'footer.html' %}
<hr>
<p style="text-align: center;">&copy; 2021 Attendance (β) | Made by <a target="_blank"
href="https://github.com/aaronleetw">Aaron Lee 李翊愷</a> for <a target="_blank"
href="https://www.fhjh.tp.edu.tw">Taipei Fuhsing Private School</a>
<br>
Consultants: Mr. Raymond Tsai 蔡瑋倫老師, Alvin Tsao 曹庭睿
</p>
</footer>
<script type=" text/javascript" src="/static/jquery.min.js"></script> <script type=" text/javascript" src="/static/jquery.min.js"></script>
<script> <script>
function loadingAnimation() { function loadingAnimation() {

View file

@ -4,7 +4,7 @@
<meta charset="utf-8"> <meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<title>Login</title> <title>Attendance 點名 - Upload</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.1/dist/css/bootstrap.min.css" rel="stylesheet" <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.1/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-F3w7mX95PdgyTmZZMECAngseQB83DfGTowi0iMjiWaeVhAn4FJkqJByhZMI3AhiU" crossorigin="anonymous"> integrity="sha384-F3w7mX95PdgyTmZZMECAngseQB83DfGTowi0iMjiWaeVhAn4FJkqJByhZMI3AhiU" crossorigin="anonymous">
<link rel="stylesheet" href="/static/allpages.css"> <link rel="stylesheet" href="/static/allpages.css">
@ -62,15 +62,7 @@
<div id="loading" style="text-align:center; width:100%; display:none;"><img src="/static/loading.gif" alt="" <div id="loading" style="text-align:center; width:100%; display:none;"><img src="/static/loading.gif" alt=""
style="height:100%;" /> style="height:100%;" />
</div> </div>
<footer> {% include 'footer.html' %}
<hr>
<p style="text-align: center;">&copy; 2021 Attendance (β) | Made by <a target="_blank"
href="https://github.com/aaronleetw">Aaron Lee 李翊愷</a> for <a target="_blank"
href="https://www.fhjh.tp.edu.tw">Taipei Fuhsing Private School</a>
<br>
Consultants: Mr. Raymond Tsai 蔡瑋倫老師, Alvin Tsao 曹庭睿
</p>
</footer>
<script type="text/javascript" src="/static/jquery.min.js"></script> <script type="text/javascript" src="/static/jquery.min.js"></script>
<script> <script>
function loadingAnimation() { function loadingAnimation() {