mirror of
https://onedev.site.tesses.net/crosslang/crosslangextras
synced 2026-02-08 17:15:45 +00:00
Add std
This commit is contained in:
@@ -3,15 +3,48 @@ func DB.Open()
|
||||
var path = DB.working / "data.db";
|
||||
return Sqlite.Open(path);
|
||||
}
|
||||
|
||||
/*func DB.GetPackageDetails(name)
|
||||
func DB.ChangeMotto(userId, motto)
|
||||
{
|
||||
DB.Lock();
|
||||
var dbCon = DB.Open();
|
||||
|
||||
Sqlite.Close(dbCon);
|
||||
Sqlite.Exec(dbCon,$"UPDATE accounts SET motto = {Sqlite.Escape(motto)} WHERE id = {userId};");
|
||||
var account = Sqlite.Exec(dbCon,$"SELECT * FROM accounts WHERE id = {userId};");
|
||||
DB.Unlock();
|
||||
}*/
|
||||
if(TypeOf(account) == "List" && account.Length > 0)
|
||||
{
|
||||
return $"/account?name={Net.Http.UrlEncode(account[0].accountName)}";
|
||||
}
|
||||
return "/";
|
||||
}
|
||||
func DB.LoginButton(ctx,active,$accountPage)
|
||||
{
|
||||
var session = DB.GetSession(ctx);
|
||||
|
||||
|
||||
if(session != null)
|
||||
{
|
||||
DB.Lock();
|
||||
var dbCon = DB.Open();
|
||||
var exec = Sqlite.Exec(dbCon,$"SELECT * FROM sessions s inner join accounts a on s.accountId = a.id WHERE key = {Sqlite.Escape(session)};");
|
||||
|
||||
Sqlite.Close(dbCon);
|
||||
DB.Unlock();
|
||||
var active2 = TypeOf(accountPage) == "String" ? accountPage == exec[0].accountName : false;
|
||||
if(TypeOf(exec) == "List" && exec.Length > 0)
|
||||
{
|
||||
return {
|
||||
active=active2,
|
||||
route = $"/account?name={Net.Http.UrlEncode(exec[0].accountName)}",
|
||||
text = exec[0].accountName
|
||||
};
|
||||
}
|
||||
}
|
||||
return {
|
||||
active,
|
||||
route = "/login",
|
||||
text = "Login"
|
||||
};
|
||||
}
|
||||
|
||||
func DB.CanUploadPackagePrefix(userId, packageName)
|
||||
{
|
||||
@@ -404,6 +437,12 @@ func DB.GetUniqueNumber()
|
||||
return unum;
|
||||
}
|
||||
|
||||
func DB.getPort()
|
||||
{
|
||||
if(TypeOf(DB.Config.Port) == "Long") return DB.Config.Port;
|
||||
return 4206;
|
||||
}
|
||||
|
||||
func DB.Init(working)
|
||||
{
|
||||
DB.working = Path.FromString(working);
|
||||
@@ -418,7 +457,7 @@ func DB.Init(working)
|
||||
if(FS.Local.FileExists(f)) FS.Local.DeleteFile(f);
|
||||
}
|
||||
|
||||
DB.mtx = Mutex();
|
||||
DB.mtx = new Mutex();
|
||||
var p = DB.working / "conf.json";
|
||||
if(FS.Local.FileExists(p))
|
||||
DB.Config = Json.Decode(FS.ReadAllText(FS.Local, p));
|
||||
@@ -430,7 +469,7 @@ func DB.Init(working)
|
||||
var dbCon = DB.Open();
|
||||
Sqlite.Exec(dbCon,"CREATE TABLE IF NOT EXISTS packages (id INTEGER PRIMARY KEY AUTOINCREMENT, packageName TEXT UNIQUE, accountId INTEGER);");
|
||||
Sqlite.Exec(dbCon,"CREATE TABLE IF NOT EXISTS versions (id INTEGER PRIMARY KEY AUTOINCREMENT, packageId INTEGER, version INTEGER, description TEXT, type TEXT, maintainer TEXT, homepage TEXT, repo TEXT, license TEXT, uploadTime INTEGER);");
|
||||
Sqlite.Exec(dbCon,"CREATE TABLE IF NOT EXISTS accounts (id INTEGER PRIMARY KEY AUTOINCREMENT, email TEXT UNIQUE, accountName TEXT UNIQUE, password_hash TEXT, password_salt TEXT, motto TEXT, verifyKey TEXT UNIQUE, flags INTEGER);");
|
||||
Sqlite.Exec(dbCon,"CREATE TABLE IF NOT EXISTS accounts (id INTEGER PRIMARY KEY AUTOINCREMENT, email TEXT UNIQUE, accountName TEXT UNIQUE, password_hash TEXT, password_salt TEXT, motto TEXT, verifyKey TEXT UNIQUE, verifyExpire INTEGER, flags INTEGER);");
|
||||
Sqlite.Exec(dbCon,"CREATE TABLE IF NOT EXISTS sessions (id INTEGER PRIMARY KEY AUTOINCREMENT, accountId INTEGER, key STRING UNIQUE);");
|
||||
Sqlite.Exec(dbCon,"CREATE TABLE IF NOT EXISTS reserved_prefixes (id INTEGER PRIMARY KEY AUTOINCREMENT, accountId INTEGER, prefix STRING UNIQUE);");
|
||||
Sqlite.Close(dbCon);
|
||||
@@ -444,6 +483,33 @@ DB.FLAG_VERIFY = 0b00000100;
|
||||
|
||||
DB.ITTR = 35000;
|
||||
|
||||
func DB.GetAccountInfo(name)
|
||||
{
|
||||
DB.Lock();
|
||||
|
||||
var dbCon = DB.Open();
|
||||
var exec = Sqlite.Exec(dbCon,$"SELECT * FROM accounts WHERE accountName = {Sqlite.Escape(name)};");
|
||||
|
||||
Sqlite.Close(dbCon);
|
||||
DB.Unlock();
|
||||
|
||||
if(TypeOf(exec) == "List")
|
||||
{
|
||||
if(exec.Length == 1)
|
||||
{
|
||||
return exec[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
return "No such user exists";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return exec;
|
||||
}
|
||||
}
|
||||
|
||||
func DB.GetAccountId(email, password)
|
||||
{
|
||||
DB.Lock();
|
||||
|
||||
@@ -21,9 +21,12 @@ func Shell(title,pages,body)
|
||||
<each(var item : pages)>
|
||||
<li class={"nav-item"}>
|
||||
<if(item.active)>
|
||||
<true>
|
||||
<a class={"nav-link active"} aria-current={"page"} href={item.route}>{item.text}</a>
|
||||
<else>
|
||||
</true>
|
||||
<false>
|
||||
<a class={"nav-link"} href={item.route}>{item.text}</a>
|
||||
</false>
|
||||
</if>
|
||||
</li>
|
||||
</each>
|
||||
|
||||
119
Tesses.CrossLang.PackageServer/src/pages/account.tcross
Normal file
119
Tesses.CrossLang.PackageServer/src/pages/account.tcross
Normal file
@@ -0,0 +1,119 @@
|
||||
func Pages.Account(ctx)
|
||||
{
|
||||
var name = ctx.QueryParams.TryGetFirst("name");
|
||||
if(TypeOf(name) != "String") name = "";
|
||||
var active = DB.LoginButton(ctx,false,name);
|
||||
|
||||
var pages = [
|
||||
{
|
||||
active = false,
|
||||
route = "/packages",
|
||||
text = "Packages"
|
||||
},
|
||||
{
|
||||
active = false,
|
||||
route = "/upload",
|
||||
text = "Upload"
|
||||
},
|
||||
active
|
||||
];
|
||||
|
||||
var user = DB.GetAccountInfo(name);
|
||||
var motto_ta = TypeOf(user.motto) == "String" ? user.motto : "";
|
||||
//var motto=Net.Http.HtmlEncode(motto_ta).Replace("\r","").Replace("\n","<br>");
|
||||
var motto = "";
|
||||
if(!active.active)
|
||||
{
|
||||
var builder = "";
|
||||
func flush()
|
||||
{
|
||||
|
||||
if(builder.Length > 0)
|
||||
{
|
||||
if(builder.StartsWith("http://") || builder.StartsWith("https://") || builder.StartsWith("ftp://") || builder.StartsWith("ftps://") || builder.StartsWith("magnet:"))
|
||||
{
|
||||
motto += <a href={builder}>{builder}</a>;
|
||||
}
|
||||
else if(builder.StartsWith("mailto:"))
|
||||
{
|
||||
motto += <a href={builder}>{builder.Substring(7)}</a>;
|
||||
}
|
||||
else if(builder.StartsWith("tel:"))
|
||||
{
|
||||
motto += <a href={builder}>{builder.Substring(4)}</a>;
|
||||
}
|
||||
else
|
||||
{
|
||||
motto += Net.Http.HtmlEncode(builder);
|
||||
}
|
||||
builder="";
|
||||
}
|
||||
}
|
||||
each(var item : motto_ta)
|
||||
{
|
||||
switch(item)
|
||||
{
|
||||
case ' ':
|
||||
flush();
|
||||
motto += " ";
|
||||
break;
|
||||
case '\n':
|
||||
flush();
|
||||
motto += "<br>";
|
||||
break;
|
||||
case '\t':
|
||||
flush();
|
||||
motto+= "&tab;";
|
||||
break;
|
||||
case '\r':
|
||||
flush();
|
||||
break;
|
||||
default:
|
||||
builder += item;
|
||||
break;
|
||||
}
|
||||
}
|
||||
flush();
|
||||
}
|
||||
|
||||
var html =
|
||||
<div class="container">
|
||||
<if(TypeOf(user) == "Dictionary")>
|
||||
<true>
|
||||
<h1>{user.accountName}</h1>
|
||||
<a href={$"./account_packages?name={Net.Http.UrlEncode(name)}"}>Packages</a>
|
||||
|
||||
|
||||
<if(active.active)>
|
||||
<true>
|
||||
<form action="./change_motto" method="POST">
|
||||
|
||||
<if(motto_ta.Length == 0)>
|
||||
<true><textarea class="form-control" name="motto" placeholder="Type your motto and/or links here" id="floatingTextarea2" style="height: 100px"></textarea></true>
|
||||
<false><textarea class="form-control" name="motto" placeholder="Type your motto and/or links here" id="floatingTextarea2" style="height: 100px">{motto_ta}</textarea></false>
|
||||
|
||||
</if>
|
||||
<input class="btn btn-primary" type="submit" value="Save">
|
||||
<input type="hidden" name="csrf" value={DB.CreateCSRF(ctx)}>
|
||||
<a class="btn btn-danger" href="./logout">Logout</a>
|
||||
</form>
|
||||
|
||||
</true>
|
||||
<false>
|
||||
<hr>
|
||||
<p><raw(motto)></p>
|
||||
</false>
|
||||
</if>
|
||||
</true>
|
||||
<false>
|
||||
<if(TypeOf(user) == "String")><true>
|
||||
<div>
|
||||
{user}
|
||||
</div>
|
||||
|
||||
</true></if>
|
||||
</false>
|
||||
</if></div>;
|
||||
|
||||
return Shell($"Account {name}", pages,html);
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
func Pages.CheckEmail()
|
||||
func Pages.CheckEmail(ctx)
|
||||
{
|
||||
var pages = [
|
||||
{
|
||||
@@ -11,11 +11,7 @@ func Pages.CheckEmail()
|
||||
route = "/upload",
|
||||
text = "Upload"
|
||||
},
|
||||
{
|
||||
active = false,
|
||||
route = "/login",
|
||||
text = "Login"
|
||||
}
|
||||
DB.LoginButton(ctx,false)
|
||||
];
|
||||
var html = <div class={"container"}>
|
||||
<h1>Please check your email.</h1>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
func Pages.Index()
|
||||
func Pages.Index(ctx)
|
||||
{
|
||||
|
||||
var pages = [
|
||||
@@ -12,11 +12,7 @@ func Pages.Index()
|
||||
route = "/upload",
|
||||
text = "Upload"
|
||||
},
|
||||
{
|
||||
active = false,
|
||||
route = "/login",
|
||||
text = "Login"
|
||||
}
|
||||
DB.LoginButton(ctx,false)
|
||||
];
|
||||
var html = <article><h1 class={"display-5"} style={"text-align: center;"}>Make crosslang development faster and more convenient with CPKG</h1><form action={"./packages"} method={"get"}><div class={"container text-center"}><div class={"row"}><div class={"col"}>
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
func Pages.Login()
|
||||
func Pages.Login(ctx)
|
||||
{
|
||||
var pages = [
|
||||
{
|
||||
@@ -11,11 +11,7 @@ func Pages.Login()
|
||||
route = "/upload",
|
||||
text = "Upload"
|
||||
},
|
||||
{
|
||||
active = true,
|
||||
route = "/login",
|
||||
text = "Login"
|
||||
}
|
||||
DB.LoginButton(ctx,true)
|
||||
];
|
||||
var html = <div class={"container min-vh-100 d-flex justify-content-center align-items-center"}>
|
||||
<form action={"./login"} method={"post"} enctype={"application/x-www-form-urlencoded"}>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
func Pages.Package(name)
|
||||
func Pages.Package(ctx,name)
|
||||
{
|
||||
var package = DB.GetPackageVersions(name);
|
||||
|
||||
@@ -13,16 +13,12 @@ func Pages.Package(name)
|
||||
route = "/upload",
|
||||
text = "Upload"
|
||||
},
|
||||
{
|
||||
active = false,
|
||||
route = "/login",
|
||||
text = "Login"
|
||||
}
|
||||
DB.LoginButton(ctx,false)
|
||||
];
|
||||
|
||||
|
||||
|
||||
var html = <if(package.Length > 0)><section class={"container"}>
|
||||
var html = <if(package.Length > 0)><true><section class={"container"}>
|
||||
<br>
|
||||
<img width={"64"} height={"64"} src={$"./api/v1/package_icon.png?name={Net.Http.UrlEncode(name)}&version={Net.Http.UrlEncode(package[0].version)}"} alt={"icon"}>
|
||||
<h1>{name}</h1>
|
||||
@@ -42,7 +38,9 @@ func Pages.Package(name)
|
||||
|
||||
<div class={"card-body"}>
|
||||
<if(package[0].type == "lib" || package[0].type == "compile_tool")>
|
||||
<true>
|
||||
crosslang add-dependency {name}
|
||||
</true>
|
||||
</if>
|
||||
</div>
|
||||
</div>
|
||||
@@ -60,16 +58,24 @@ func Pages.Package(name)
|
||||
<ul>
|
||||
<li>Account: <a href={$"./account?name={Net.Http.UrlEncode(package[0].accountName)}"}>{package[0].accountName}</a></li>
|
||||
<if(package[0].maintainer.Length > 0)>
|
||||
<true>
|
||||
<li>Maintainer: {package[0].maintainer}</li>
|
||||
</true>
|
||||
</if>
|
||||
<if(package[0].license.Length > 0)>
|
||||
<true>
|
||||
<li>License: {package[0].license}</li>
|
||||
</true>
|
||||
</if>
|
||||
<if(package[0].homepage.Length > 0)>
|
||||
<true>
|
||||
<li>Homepage: <a href={package[0].homepage}>{package[0].homepage}</a></li>
|
||||
</true>
|
||||
</if>
|
||||
<if(package[0].repo.Length > 0)>
|
||||
<true>
|
||||
<li>Repo: <a href={package[0].repo}>{package[0].repo}</a></li>
|
||||
</true>
|
||||
</if>
|
||||
<li>Last updated: {package[0].uploadDate}</li>
|
||||
<li>Latest version: {package[0].version}</li>
|
||||
@@ -77,6 +83,7 @@ func Pages.Package(name)
|
||||
<li><a href={package[0].download}>Download</a></li>
|
||||
</ul>
|
||||
<if(package.Length > 1)>
|
||||
<true>
|
||||
<br>
|
||||
|
||||
<h3>Older versions</h3>
|
||||
@@ -92,16 +99,24 @@ func Pages.Package(name)
|
||||
<div class={"accordion-body"}>
|
||||
<ul>
|
||||
<if(package[i].maintainer.Length > 0)>
|
||||
<true>
|
||||
<li>Maintainer: {package[i].maintainer}</li>
|
||||
</true>
|
||||
</if>
|
||||
<if(package[i].license.Length > 0)>
|
||||
<true>
|
||||
<li>License: {package[i].license}</li>
|
||||
</true>
|
||||
</if>
|
||||
<if(package[i].homepage.Length > 0)>
|
||||
<true>
|
||||
<li>Homepage: <a href={package[i].homepage}>{package[i].homepage}</a></li>
|
||||
</true>
|
||||
</if>
|
||||
<if(package[i].repo.Length > 0)>
|
||||
<true>
|
||||
<li>Repo: <a href={package[i].repo}>{package[i].repo}</a></li>
|
||||
</true>
|
||||
</if>
|
||||
<li>Uploaded: {package[i].uploadDate}</li>
|
||||
<li>Type: {package[i].type}</li>
|
||||
@@ -113,8 +128,9 @@ func Pages.Package(name)
|
||||
|
||||
</for>
|
||||
</div>
|
||||
</true>
|
||||
</if>
|
||||
</section>
|
||||
</section></true>
|
||||
</if>;
|
||||
return Shell($"Package {name}", pages,html);
|
||||
}
|
||||
|
||||
@@ -13,11 +13,7 @@ func Pages.Packages(ctx)
|
||||
route = "/upload",
|
||||
text = "Upload"
|
||||
},
|
||||
{
|
||||
active = false,
|
||||
route = "/login",
|
||||
text = "Login"
|
||||
}
|
||||
DB.LoginButton(ctx,false)
|
||||
];
|
||||
var html = <article><form action={"./packages"} method={"get"}><div class={"container text-center"}><div class={"row"}><div class={"col"}>
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
func Pages.Signup()
|
||||
func Pages.Signup(ctx)
|
||||
{
|
||||
var pages = [
|
||||
{
|
||||
@@ -11,11 +11,7 @@ func Pages.Signup()
|
||||
route = "/upload",
|
||||
text = "Upload"
|
||||
},
|
||||
{
|
||||
active = false,
|
||||
route = "/login",
|
||||
text = "Login"
|
||||
}
|
||||
DB.LoginButton(ctx,false)
|
||||
];
|
||||
var html = <div class={"container min-vh-100 d-flex justify-content-center align-items-center"}>
|
||||
<form action={"./signup"} method={"post"} enctype={"application/x-www-form-urlencoded"}>
|
||||
|
||||
@@ -11,12 +11,9 @@ func Pages.Upload(ctx)
|
||||
route = "/upload",
|
||||
text = "Upload"
|
||||
},
|
||||
{
|
||||
active = false,
|
||||
route = "/login",
|
||||
text = "Login"
|
||||
}
|
||||
DB.LoginButton(ctx,false)
|
||||
];
|
||||
|
||||
var html = <div class={"container min-vh-100 d-flex justify-content-center align-items-center"}>
|
||||
<form action={"./upload"} method={"post"} enctype={"multipart/form-data"}>
|
||||
<h1>Upload Package</h1>
|
||||
|
||||
@@ -36,7 +36,7 @@ func main(args)
|
||||
{
|
||||
var name = ctx.QueryParams.TryGetFirst("name");
|
||||
if(TypeOf(name) != "String") name = "";
|
||||
ctx.WithMimeType("text/html").SendText(Pages.Package(name));
|
||||
ctx.WithMimeType("text/html").SendText(Pages.Package(ctx,name));
|
||||
return true;
|
||||
}
|
||||
if(ctx.Path == "/packages")
|
||||
@@ -78,6 +78,34 @@ func main(args)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if(ctx.Path == "/change_motto")
|
||||
{
|
||||
if(ctx.Method == "POST")
|
||||
{
|
||||
var motto = ctx.QueryParams.TryGetFirst("motto");
|
||||
if(motto == null) motto = "";
|
||||
var session = DB.GetSession(ctx);
|
||||
if(session == null)
|
||||
{
|
||||
ctx.StatusCode = 401;
|
||||
ctx.SendText("<h1>You are not logged in</h1>");
|
||||
return true;
|
||||
}
|
||||
|
||||
var csrf = ctx.QueryParams.TryGetFirst("csrf");
|
||||
var result = { Success=false, Reason = "Invalid CSRF"};
|
||||
|
||||
if(DB.VerifyCSRF(session,csrf))
|
||||
{
|
||||
var userId = DB.GetUserIdFromSession(session);
|
||||
var url = DB.ChangeMotto(userId,motto);
|
||||
ctx.StatusCode = 302;
|
||||
ctx.ResponseHeaders.SetValue("Location", url);
|
||||
ctx.WriteHeaders();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(ctx.Path == "/upload")
|
||||
{
|
||||
if(ctx.Method == "GET")
|
||||
@@ -96,13 +124,13 @@ func main(args)
|
||||
|
||||
if(name == "package")
|
||||
{
|
||||
if(hasFile) return FS.MemoryStream(true);
|
||||
if(hasFile) return new MemoryStream(true);
|
||||
hasFile=true;
|
||||
|
||||
return strm;
|
||||
}
|
||||
else
|
||||
return FS.MemoryStream(true);
|
||||
return new MemoryStream(true);
|
||||
});
|
||||
|
||||
strm.Close();
|
||||
@@ -110,6 +138,9 @@ func main(args)
|
||||
var session = DB.GetSession(ctx);
|
||||
if(session == null)
|
||||
{
|
||||
|
||||
if(FS.Local.FileExists(filePath))
|
||||
FS.Local.DeleteFile(filePath);
|
||||
ctx.StatusCode = 401;
|
||||
ctx.SendText("<h1>You are not logged in</h1>");
|
||||
return true;
|
||||
@@ -179,7 +210,7 @@ func main(args)
|
||||
{
|
||||
if(ctx.Method == "GET")
|
||||
{
|
||||
ctx.WithMimeType("text/html").SendText(Pages.Login());
|
||||
ctx.WithMimeType("text/html").SendText(Pages.Login(ctx));
|
||||
return true;
|
||||
}
|
||||
else if(ctx.Method == "POST")
|
||||
@@ -219,7 +250,7 @@ func main(args)
|
||||
{
|
||||
if(ctx.Method == "GET")
|
||||
{
|
||||
ctx.WithMimeType("text/html").SendText(Pages.Signup());
|
||||
ctx.WithMimeType("text/html").SendText(Pages.Signup(ctx));
|
||||
return true;
|
||||
}
|
||||
else if(ctx.Method == "POST")
|
||||
@@ -275,6 +306,11 @@ func main(args)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if(ctx.Path == "/account")
|
||||
{
|
||||
ctx.WithMimeType("text/html").SendText(Pages.Account(ctx));
|
||||
return true;
|
||||
}
|
||||
if(ctx.Path == "/css/bootstrap.min.css")
|
||||
{
|
||||
ctx.WithMimeType("text/css").SendBytes(embed("css/bootstrap.min.css"));
|
||||
@@ -304,9 +340,10 @@ func main(args)
|
||||
}
|
||||
if(ctx.Path == "/")
|
||||
{
|
||||
ctx.WithMimeType("text/html").SendText(Pages.Index());
|
||||
ctx.WithMimeType("text/html").SendText(Pages.Index(ctx));
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
},4206);
|
||||
},DB.Port);
|
||||
}
|
||||
Reference in New Issue
Block a user